8

我正在尝试尽可能多地收集有关在 Mac OS 10.11.1 'El Capitan' 上使用 Valgrind 3.11.0 时看到的明显无限循环问题的信息。

当我valgrind在 LLDB 中运行我的程序或附加到valgrind运行我的程序然后停止该进程时,我得到如下回溯:

* 线程 #1:tid = 0x24ab4, 0x000000010805920b,停止原因 = 信号 SIGSTOP
  * 帧#0:0x000000010805920b
    帧#1:0x0000000108040dda
    帧#2:0x00000001080b6790
    帧#3:0x00000001080b2fd3
    帧#4:0x00000001080b7c25
    帧#5:0x00000001080b6113
    帧#6:0x00000001080b3cd0
    第 7 帧:0x00000001080c54d9

如何判断这些框架对应于哪些对象?

我尝试vmmap了这个过程,但它没有显示任何信息。特别是,“进程的不可写区域”部分通常会显示 dylib 映射到进程内存的地址范围是空白的:

$ 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位进程
虚拟机页面大小:4096 字节

==== 进程 21729 的不可写区域
区域类型开始 - 结束 [ VSIZE RSDNT DIRTY SWAP] PRT/MAX SHRMOD 清除区域详细信息

==== 进程 21729 的可写区域
区域类型开始 - 结束 [ VSIZE RSDNT DIRTY SWAP] PRT/MAX SHRMOD 清除区域详细信息

==== 图例
SM=共享模式:  
    COW=copy_on_write PRV=private NUL=empty ALI=aliased
    SHM=shared ZER=zero_filled S/A=shared_alias
PURGE=可吹扫模式:  
    V=volatile N=nonvolatile E=empty 否则不可清除

==== 进程 21729 的摘要
(无效的)
4

2 回答 2

11
(lldb) image lookup -va <ADDRESS>

将显示有关给定地址的大量信息,并且:

(lldb) image list

将列出所有库,并且

(lldb) image dump sections

将转储有关所有已加载库的部分位置的详细信息。

但是,如果 lldb 能够确定在帧打印中的给定地址映射了哪个库,它就会表明(除非您更改了帧格式设置。)因此这些命令可能不会向您显示更多信息任何一个。

请注意,valgrind 对程序的执行做了一些奇怪的事情来发挥它的魔力,如果像 lldb 和 vmmap 这样的外部工具无法看到潜在的真相,我一点也不感到惊讶。

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

于 2015-11-30T19:56:49.463 回答
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

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

于 2015-12-03T03:04:19.447 回答