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

Dre*_*rew 15 lldb swift

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

<MySpecialObject:0x7a5125a0 This is a description of my special object>
Run Code Online (Sandbox Code Playgroud)

在ObjC调试器中,我可以做一些事情,比如po [0x7a5125a0 myMethod:arg1 arg2:arg2]在调试器中与这个对象进行交互.

我也可以这样做:

(lldb) expr MySpecialObject *$foo = 0x7a5125a0
(lldb) po [foo myMethod:arg1 arg2:arg2]
Run Code Online (Sandbox Code Playgroud)

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

Enr*_*ata 23

您可以尝试的一件事是:

(lldb) expr -l objc++ -O -- [(id)0xmyFancyAddressGoesHere selector]
Run Code Online (Sandbox Code Playgroud)

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

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


Wal*_*ter 10

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

expr $mv = unsafeBitCast(0x7a66cdb0, MapView.self)
Run Code Online (Sandbox Code Playgroud)

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

Swift 4的更新:似乎Xcode 10.1中的语法略有变化,因此unsafeBitCast部件现在需要命名第二个参数并添加一个let(或者可能是var依赖的).所以,上面的例子现在变成了

expr let $mv = unsafeBitCast(0x7a66cdb0, to: MapView.self)
Run Code Online (Sandbox Code Playgroud)


mat*_*att 4

没有这样的办法。调试 Swift 几乎是不可能的。暂停时表达式的求值和变量的检查完全被破坏了。你现在最好使用printlnor 。NSLog

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

  • 大大改进了..那么现在有没有办法引用内存地址?:/ (7认同)