Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

po in LLDB with swift

Tags:

swift

lldb

How can I plot out variable's value in a Swift App with LLDB?

Earlier it was like po variable_name

Now I usually get some nasty error, like:

(lldb) po a error: <EXPR>:11:5: error: use of unresolved identifier '$__lldb_injected_self'     $__lldb_injected_self.$__lldb_wrapped_expr_2(          ^ 
like image 658
János Avatar asked Jul 16 '14 16:07

János


People also ask

What is PO in LLDB?

1. The po command is added to the built-in command set in lldb using: "command alias po expr -O --". If you run help po the last line in the output is: "'po' is an abbreviation for 'expression -O --'. The -- indicates the end of the command options, so all your input on the line is your expression.

What is LLDB in Swift?

LLDB is a high-performance debugger and next generation of GNU Debugger. It contains a set of libraries, such as Clang expression parser and LLVM disassembler. LLDB is the system debugger on macOS, iPadOS, iOS, tvOS, and watchOS. It can also be used for Objective-C and Swift development for architectures: x86_64.

What is the use of PO command in Xcode?

Well, you can get help from the debugger itself. At the (lldb) prompt in the Xcode console pane (the app must be launched but paused, you can't type commands if it's running), you can type "help po". In this case it's shorthand for another command, which the help explains to you.

What is the difference between P and Po?

Summary. The po command uses the object description, whereas the p and v commands use the data formatters to display the object on the console. A second important difference is that both po and p compile expressions and then execute them and have access to the full language.


2 Answers

That error sounds like it might be because DWARF is not telling LLDB where to find your self object. Given the nature of Swift, LLDB needs to know the type of self in order to be able to inject an expression inside your local scope. One way to find out if that is your problem is to do at the LLDB prompt:

(lldb) frame variable -L self 

You are probably going to not see a location for it. Worth filling a bug report for, just to track your specific repro case.

Anyway, to get to the bulk of your question. In Swift, there is no language-sanctioned mechanism for "print description" like for ObjC, so while you can type po self, unless self is an Objective-C type, you will pretty much see the same thing that "p self" or even "frame variable self" would tell you - which is entirely based on the LLDB data formatters mechanism. If you want to hook into that to customize the way your Swift objects look, the obligatory reference is: http://lldb.llvm.org/varformats.html

like image 120
Enrico Granata Avatar answered Oct 21 '22 03:10

Enrico Granata


I have made a few tests to figure out how it works with Swift, results surprised me a bit. With ObjC objects po calls debugDescription which by default calls description. That is clear. Unfortunately the same doesn't apply while working with Swift classes. I focused on objects rather than on printing single variables.

To make it working (po command in lldb) I had to override description. Below code I used for testing:

class Test : NSObject {     var name : String?     var surname : String?      override var debugDescription : String{         return "debugDescription method"     }      override var description : String {         return "description Method"     } } 

Testing:

let test = Test() test.name = "name" test.surname = "surname"  (lldb) po test description Method  (lldb) p test (DebugTest.Test) $R1 = 0x00007fce11404860 {   ObjectiveC.NSObject = {     isa = DebugTest.Test   }   name = "name"   surname = "surname" }  (lldb) po dump(test) ▿ DebugTest.Test #0   - super: debugDescription method   ▿ name: name     - Some: name   ▿ surname: surname     - Some: surname description Method  (lldb) po print(test) description Method 

The thing that surprised me is that po on Swift objects calls description rather than debugDescription that differs from ObjC.

EDIT

To make it acting like with ObjC, Your class have to implement CustomDebugStringConvertible and then po will call debugDescription, which by default calls description. The only thing which have to be changed in my example would be adding:

class Test : NSObject, CustomDebugStringConvertible 

Reference

Checked with XCode 7.0.1 and iOS SDK 9, Swift 2.0

like image 40
Julian Avatar answered Oct 21 '22 03:10

Julian