LLDB - 如何打印全局变量的值?

3
在我的情况下,堆栈没有被正确解码,因此我无法使用与帧相关的命令。我试图使用某种绝对名称从特定模块中读取变量。
我已经成功找到了该变量:
(lldb) image lookup -s os::_mem_serialize_page libjvm.dylib
Address: libjvm.dylib[0x00000000009bd690] (libjvm.dylib.__DATA.__common + 151184)
Summary: libjvm.dylib`os::_mem_serialize_page

然而,我不知道如何读取它的值。
(lldb) print os::_mem_serialize_page
error: use of undeclared identifier 'os'

(lldb) print libjvm.dylib`os::_mem_serialize_page
error: use of undeclared identifier 'libjvm'

(lldb) x/g libjvm.dylib[0x00000000009bd690]
error: invalid start address expression.
error: address expression "libjvm.dylib[0x00000000009bd690]" evaluation failed

我找到的唯一方法

查找地址,方法1

(lldb) image lookup -v -s os::_mem_serialize_page libjvm.dylib
Address: libjvm.dylib[0x00000000009bd690] (libjvm.dylib.__DATA.__common + 151184)
Summary: libjvm.dylib`os::_mem_serialize_page
 Module: <snip>
 Symbol: id = {0x0000e81e}, range = [0x000000010ee46690-0x000000010ee46698), name="os::_mem_serialize_page", mangled="_ZN2os19_mem_serialize_pageE"

查找地址,方法二

(lldb) image dump symtab libjvm.dylib
Index   UserID DSX Type            File Address/Value Load Address       Size               Flags      Name
------- ------ --- --------------- ------------------ ------------------ ------------------ ---------- ----------------------------------
[59422]  59422     Data            0x00000000009bd690 0x000000010ee46690 0x0000000000000008 0x001e0000 os::_mem_serialize_page

读取地址中的内存以获取变量的值

(lldb) x/g 000000010ee46690
0x10ee46690: 0x0000000000000000

但这很不方便,因为需要多个步骤并且我必须自己指定变量类型。

2个回答

2
如果您有要打印的符号的调试信息,则您的“print”尝试应该会成功。但是看起来您没有此符号所在库的调试信息,否则“image lookup -v”将会打印出定义编译单元。
然而,您确实拥有该符号(您的“image lookup -v”命令找到了它)。所以您应该能够从该符号中打印出值。
问题是,如果您给lldb提供了已解码的名称“os::_mem_serialize_page”,它将开始尝试查找“os”(这样它就可以在该类或命名空间中找到_mem_serialize_page)。由于没有类型,它将不知道“os”的任何信息,并在那里停止。
但是,如果您提供了mangled名称,lldb将直接从符号表中查找它,并可以从那里到达地址。这将省去上述步骤之一。
但是,无论如何都必须告诉lldb变量类型。没有调试信息,lldb无法知道类型,也不能真正打印该值。

很抱歉让你感到困惑,我从 image lookup -v 中剪切了模块信息。当然我有调试信息,否则 image lookup -v 将无法找到它。符号名称混淆是一个有趣的点。你知道如何解决这个问题并说服 LLDB 接受混淆后的名称吗?否则,这仍然是一个繁琐的步骤,我宁愿避免它。 - Codeguard
image lookup -v -s 将查找符号名称以及调试信息,因此它找到 os::_mem_serialize_page 并不意味着您拥有 libjvm.dylib 的调试信息,或者在任何情况下都是如此。如果您有调试信息,那么必须为 CompileUnit 再添加另一个条目。您也将其剪切了吗? - Jim Ingham

1

参考 Jim Ingham 关于 image lookup -v 的提示,我发现可以通过变量的 mangled 名称来读取变量:

  1. 确定 mangled 名称:
(lldb) image lookup -v -s os::_mem_serialize_page libjvm.dylib
<snip> name="os::_mem_serialize_page", mangled="_ZN2os19_mem_serialize_pageE" <snip>

从现在开始,可以使用这个名称来读取变量。
(lldb) p _ZN2os19_mem_serialize_pageE
(void *) $5 = 0x0000000000000000

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