如何让LLDB打印内存中共享库的位置?

12
我正在尝试收集关于在Mac OS 10.11.1 'El Capitan'上使用Valgrind 3.11.0时看到的明显的无限循环问题的尽可能多的信息。
当我在LLDB中运行valgrind或附加到运行我的程序的valgrind然后停止进程时,我会得到以下类似的回溯:
* 线程#1:tid = 0x24ab4,停止原因=信号SIGSTOP * 帧#0:0x000000010805920b 帧#1:0x0000000108040dda 帧#2:0x00000001080b6790 帧#3:0x00000001080b2fd3 帧#4:0x00000001080b7c25 帧#5:0x00000001080b6113 帧#6:0x00000001080b3cd0 帧#7:0x00000001080c54d9
我该如何确定这些帧对应哪个对象?
我尝试在进程上使用 vmmap,但它没有显示任何信息。特别是,“进程的非可写区域”部分通常会显示 dylibs 映射到进程内存中的地址范围,但现在为空白:
$ vmmap -v 21729
进程:            memcheck-amd64-darwin [21729]
路径:            /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/memcheck-amd64-darwin
加载地址:        0x100000000
标识符:          memcheck-amd64-darwin
版本:            ???
代码类型:        X86-64
父进程:          bash [11895]
日期/时间: 2015-11-30 11:52:16.392 -0500 启动时间: 2015-11-30 11:51:53.557 -0500 操作系统版本: Mac OS X 10.11.1 (15B42) 报告版本: 7 分析工具: /Applications/Xcode.app/Contents/Developer/usr/bin/vmmap 分析工具版本: Xcode 7.1.1 (7B1005) ----
进程21729(memcheck-amd64-darwin)的虚拟内存映射 输出报告格式:2.4--64位进程 VM页面大小:4096字节
==== 进程21729的不可写区域 REGION TYPE START - END [ VSIZE RSDNT DIRTY SWAP] PRT/MAX SHRMOD PURGE REGION DETAIL
==== 进程21729的可写区域 REGION TYPE START - END [ VSIZE RSDNT DIRTY SWAP] PRT/MAX SHRMOD PURGE REGION DETAIL
==== 图例 SM = 分享模式: COW = 写时复制 PRV = 私有 NUL = 空 ALI = 别名 SHM = 共享 ZER = 零填充 S/A = 共享别名 PURGE = 可清除模式: V = 易失性 N = 非易失性 E = 空,否则是不可清除的
==== 进程21729的摘要 (null)
2个回答

15
(lldb) image lookup -va <ADDRESS>

将显示给定地址的大量信息,而且:

(lldb) image list

将列出所有的库,并

(lldb) image dump sections

该命令将详细信息转储有关所有已加载库的节位置。

但是,如果lldb能够确定在打印的帧中映射了哪个库(除非您更改了frame-format设置),它将显示这一点。因此,这些命令可能也不会向您显示更多信息。

请注意,valgrind执行您的程序时会进行奇怪的操作以发挥其魔力,如果像lldb和vmmap这样的外部工具无法看到底层真相,则一点也不奇怪。

由于您拥有最新的操作系统和工具,您可以尝试使用llvm的ASAN而不是valgrind,看看它是否能捕获您的问题。 ASAN需要重新构建,但由于它使用静态技巧,因此运行时对其他工具来说看起来是正常的。


谢谢,这回答了我的问题。不幸的是,尝试使用这些命令会导致“错误:目标没有关联的可执行映像”,但我想当在valgrind上使用LLDB时,这是可以预料的。 - Daniel Trebbien
@DanielTrebbien,我对这个结果感到惊讶。我在我的机器上尝试了一下,它运行得很好(虽然它列出了valgrind的内存映射,而不是嵌套的客户端可执行文件)。_那_是可以预料的。当然,这个评论现在已经超过2年了.. - sherrellbc

1
自从我使用valgrind以来已经很久了,我完全忘记了它的调试方式...要调试在valgrind下运行的程序,您必须告诉valgrind为调试器打开一个gdbserver端口。Valgrind知道如何撤消所有魔法,并假装它正在管理的程序只是普通的程序...这在第3.2节中描述:http://valgrind.org/docs/manual/manual-core-adv.html。LLDB也知道如何使用gdb远程协议进行通信,并具有一个gdb-remote命令来连接到服务器。这不能直接在lldb上工作,似乎存在一些寄存器定义问题。看起来valgrind有一些改进的工作:

https://bugs.kde.org/show_bug.cgi?id=356174

无论如何,这就是它应该工作的方式。

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