2

我经常从 libunwind 或 AddressSanitizer 获取堆栈跟踪,如下所示:

#12 0x7ffff4b47063 (/home/janw/src/pl-devel/lib/x86_64-linux/libswipl.so.7.1.13+0x1f5063)
#13 0x7ffff4b2c783 (/home/janw/src/pl-devel/lib/x86_64-linux/libswipl.so.7.1.13+0x1da783)
#14 0x7ffff4b2cca4 (/home/janw/src/pl-devel/lib/x86_64-linux/libswipl.so.7.1.13+0x1daca4)
#15 0x7ffff4b2cf42 (/home/janw/src/pl-devel/lib/x86_64-linux/libswipl.so.7.1.13+0x1daf42)

我知道如果我将 gdb 附加到仍然存在的进程,我可以使用它来获取有关位置的详细信息:

(gdb) list *0x7ffff4b47063

但是如果进程已经死了,我不能只是在 gdb 下重新启动它并使用上面的方法,因为地址随机化会使我得到错误的结果(至少,这是我的假设;我显然没有得到有意义的位置)。所以,我尝试了

% gdb program
% run
<get to the place everything is loaded and type Control-C>
(gdb) info shared
<Dumps mapping location of shared objects>
(gdb) list *(<base of libswipl.so.7.1.13>+0x1f5063)

但是,这要么没有列出任何内容,要么显然是错误的位置。这听起来很简单,但我没有找到答案:-( 平台是 64 位 Linux,但我想这适用于任何平台。

4

2 回答 2

2

(gdb) info shared
<Dumps mapping location of shared objects>

不幸的是,上面并没有转储可用于此的实际映射位置:

libswipl.so.7.1.13+0x1f5063

(正如你所发现的)。相反,GDB 输出列出了该.text部分的映射位置,而不是 ELF 二进制文件本身的映射位置。

您可以.text通过在中找到它来调整偏移量

readelf -WS libswipl.so.7.1.13 | grep '\.text'

相反,它可能更容易使用addr2line。就像是

addr2line -fe libswipl.so.7.1.13 0x1f5063 0x1da783

应该管用。

于 2014-04-23T14:16:46.613 回答
1

有关使用 asan_symbolize.py 脚本和/或 symbolize=true 选项的说明,请参阅http://clang.llvm.org/docs/AddressSanitizer.html

于 2014-04-30T09:49:55.797 回答