与调试器中的内存位置的swift对象进行交互

时间:2014-08-24 01:43:39

标签: swift lldb

假设我知道,根据早期的控制台输出,在某个内存位置是一个感兴趣的对象:

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

在ObjC调试器中,我可以执行po [0x7a5125a0 myMethod:arg1 arg2:arg2]之类的操作来与调试器中的此对象进行交互。

我也可以这样做:

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

调试Swift程序时,实现此效果的方法是什么(在lldb中与对象进行交互,并给出其内存地址)?

4 个答案:

答案 0 :(得分:23)

您可以尝试的一件事是:

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

你的里程可能会有所不同,但基本上这是你在ObjC中所做的美化版本(除了现在你在Swift-land中,所以你必须在ObjC模式下强制表达式评估器(-l objc ++),并且你不能依赖“po”别名,所以你需要明确要求“对象描述行为”(-O)

当然,如果你发现自己经常这样做,你可以为“expr -l objc ++ -O - ”创建自己的别名

答案 1 :(得分:10)

在Swift中,您使用unsafeBitcast函数将内存地址转换为lldb中的变量。

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

这会将内存地址转换为MapVie对象。当您构建自己的对象时,您可能会发现必须将import项目的模块放入lldb。

Swift 4的更新: 似乎Xcode 10.1中的语法略有变化,因此unsafeBitCast部分现在需要命名第二个参数,我们添加let(或者var取决于)。所以,上面的例子现在变成了

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

答案 2 :(得分:4)

没有这样的方法。调试Swift几乎不是一个启动器。在暂停时对表达式和变量检查的评估完全被打破。最好现在使用printlnNSLog

编辑那是一年前的事了。 LLDB现在大大改进了与Swift的使用!

答案 3 :(得分:3)

版本6.1.1(6A2008a) 我正在调试视图层次结构。我有自己的UIImage视图子类。这就是它对我有用的方式:

(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

显然它是一个UIView子类,所以它是objective-c,但它与Swift混合。