我经常从 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,但我想这适用于 任何平台。
最佳答案
(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
应该可以。
关于gdb - 如何从 libunwind 和 AddressSanitizer 中获取列为 <共享对象> + 偏移量的行号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23240817/