lldb: 打印变量的地址

26

我正在尝试使用lldb打印变量的地址。然而,调用print &(myVar)会打印变量的内容,而不是它的地址。

(lldb) print &(myVar)
(const string *) $18 = "hello"

同样适用于expression &(myVar)

(lldb) expression &(myVar)
(const string *) $19 = "hello"

我也尝试了expression-L选项:

(lldb) expression -L -- &(myVar)
0x00000000021aea80: (const string *) $20 = "hello"

(lldb) expression -L -- myVar
0x0000000002a15430: (std::string) $23 = "hello"

然而,每次我调用expression -L时,输出的地址都会更改。因此,我认为它不对应于变量在内存中的地址。

我如何获得变量在内存中的地址?

(我使用lldb 3.4)

2个回答

38

是的,-L位置告诉您lldb用于表示表达式结果的变量,这不是您想要的。尽管常见的命令别名“print”使该命令看起来只是打印值,但它实际上做了更多的事情:例如,在运行程序中创建新实体。因此,表达式结果的位置与您评估的表达式并不是一一对应的。

无论如何,有两种简单的方法可以解决这个问题。第一种是关闭字符串摘要,这样您就可以看到打印地址的实际结果:

(lldb) expr --raw -- &my_string
(string *) $14 = 0x00007fff5fbff618

使用“frame variable”命令是获取相同数据的另一种方法。该命令可以访问本地变量,而不需要完整表达式解析器的开销。由于frame variable直接按照调试信息报告打印变量,因此在这种情况下,-L选项正好是变量的位置:

(lldb) frame var -L my_string
0x00007fff5fbff618: (std::__1::string) my_string = "Some string here"

感谢您的详细回答! - Gael Lorieul
当self是一个对象时,有没有更好的打印self地址的方法?如果使用expr --raw -- &self,会返回错误:error: use of extraneous '&'。我发现唯一的方法是将深度限制为零:frame var -L -D 0 self,但这似乎有点别扭。 - Jason Moore
从错误中我推断出你正在调试Swift代码?在ObjC中,这个代码是按预期工作的。Swift不使用&作为“地址”,所以那不是有效的Swift代码,因此会出现错误。作为一种“内存安全”的语言,Swift对于展示变量存储位置没有太大兴趣。你可能可以使用Unsafe...方法来找到一个有效的Swift表达式,返回变量的位置?但是在那一点上,你将与Swift的设计相抵触。 - Jim Ingham

0
请允许我对上面@Jim Ingham的出色回答进行补充。
关于这个主题,有一个非常好的教程可供参考查看堆栈帧状态
虽然可能需要几分钟的时间,但一个好的提示是首先使用以下命令转储所有可用的堆栈帧变量:
frame variable

确认所需变量可用后,可以运行以下命令:
frame variable myVar

或者,按照提到的地址进行包含。
frame variable -L myVar

个人而言,我喜欢添加一个 Xcode 调试操作 - 在不暂停执行的情况下 - 如下所示:

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接