Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interact with swift object with memory location in the debugger

Tags:

swift

lldb

Suppose I know, based on earlier console output, that at some memory location is an object of interest:

<MySpecialObject:0x7a5125a0 This is a description of my special object>

In the ObjC debugger I could do something like po [0x7a5125a0 myMethod:arg1 arg2:arg2] to interact with this object in the debugger.

I could also do this:

(lldb) expr MySpecialObject *$foo = 0x7a5125a0
(lldb) po [foo myMethod:arg1 arg2:arg2]

What is the way to accomplish this effect (interact with object in lldb given its memory address) when debugging a Swift program?

like image 874
Drew Avatar asked Aug 24 '14 01:08

Drew


4 Answers

One thing you could try is the following:

(lldb) expr -l objc++ -O -- [(id)0xmyFancyAddressGoesHere selector]

Your mileage may vary but essentially this is the glorified version of what you would do in ObjC (except that now you're in Swift-land so you have to force the expression evaluator in ObjC mode (-l objc++), and you can't rely on the "po" alias, so you need to explicitly ask for "object description behavior" (-O)

Of course, if you find yourself doing this often, you can make your own alias for "expr -l objc++ -O --"

like image 116
Enrico Granata Avatar answered Oct 20 '22 01:10

Enrico Granata


In Swift you use the unsafeBitcast function to cast a memory address to a variable in lldb.

expr $mv = unsafeBitCast(0x7a66cdb0, MapView.self)

This would cast the memory address to a MapVie object. When you're casting your own objects, you may find that you have to import your project's module into lldb.

Update for Swift 4: it appears that the syntax changes slightly in Xcode 10.1 so the unsafeBitCast part now needs to name the second parameter and we add a let (or maybe var depending). So, the example above now becomes

expr let $mv = unsafeBitCast(0x7a66cdb0, to: MapView.self)
like image 40
Walter Avatar answered Oct 19 '22 23:10

Walter


There is no such way. Debugging Swift is pretty much a non-starter. Evaluation of expressions and inspection of variables while paused is totally broken. You're better off using println or NSLog for now.

EDIT That was a year ago. LLDB is greatly improved for use with Swift now!

like image 30
matt Avatar answered Oct 20 '22 00:10

matt


Version 6.1.1 (6A2008a) I am debugging the view hierarchy. I have my own subclass of UIImage view. Here it is how it works for me :

(lldb) po 0x7fc6ecb55e30

<Lesson_1_Quartz_Composer.Layer: 0x7fc6ecb55e30; baseClass = UIImageView; frame = (0 0; 320 49.5); opaque = NO; gestureRecognizers = <NSArray: 0x7fc6ecb6df20>; layer = <CALayer: 0x7fc6ecb55f30>>

(lldb) po [0x7fc6ecb55e30 isUserInteractionEnabled]
0x0000000182002001

(lldb) po (bool)[0x7fc6ecb55e30 isUserInteractionEnabled]
true

(lldb)  expr -l objc++ -O -- [(id)0x7fc6ecb55e30 isUserInteractionEnabled]
0x0000000182002001

Obviously it is a UIView subclass, so it objective-c, but it mixes with Swift.

like image 43
Adrian Avatar answered Oct 20 '22 00:10

Adrian