使用gdb将地址转换为行

问题描述 投票:0回答:2

我有一个由剥离的应用程序生成的堆栈跟踪,如下所示:

 *** Check failure stack trace: ***
    @     0x7f0e442d392d  (unknown)
    @     0x7f0e442d7b1f  (unknown)
    @     0x7f0e442d7067  (unknown)
    @     0x7f0e442d801d  (unknown)
    @     0x7f0e457c55e6  (unknown)
    @     0x7f0e457c5696  (unknown)
    @           0x4e8765  (unknown)
    @           0x4a8b43  (unknown)
    @     0x7f0e43197ced  (unknown)
    @           0x4a6889  (unknown)

我有一个未剥离版本的可执行文件及其所有库(使用调试信息编译)。但是我怎样才能将地址转换成文件和行号呢?

这是我尝试过的:

gdb
set solib-absolute-prefix /path/to/non-stripped/edition/of/root/filesystem/sysroot/
file /path/to/non-stripped/edition/of/root/filesystem/sysroot/usr/bin/my-buggy-app
info line *0x7f0e457c5696

当我输入文件命令时,它仅从文件中加载符号,而不是所有使用的库。有没有办法可以做到这一点?

“信息行”命令表示:

地址 0x7f0e442d801d 没有可用的行号信息

我认为是因为该地址位于其中一个共享库中,但我如何知道位于其中哪个共享库中?

c linux gdb
2个回答
58
投票

根据OP,GDB中从某个地址查找源代码行的命令是:

info line *0x10045740

编辑:替换了“信息符号0x10045740”,该符号在某些条件下不起作用(感谢@Thomasa88)。


39
投票

但是如何将地址转换为文件和行号呢?

对于主要可执行文件(类似

0x4e8765
的地址),请执行以下操作:

addr2line -e /path/to/non-stripped/.../my-buggy-app \
    0x4a6889 0x4a8b43 0x4e8765

实际上,您可能想从上述所有地址中减去

5
CALL
指令的通常长度)。

对于共享库中的地址,你必须知道库的加载地址。

如果您的应用程序生成了

core
文件,那么
(gdb) info shared
将告诉您加载库的位置。

如果您没有获得核心文件,并且应用程序没有打印所需的映射,那么

  • 您应该修复应用程序,以便它确实打印该信息(如果没有它,堆栈跟踪几乎毫无用处),并且
  • 您仍然可以猜测:查看
    0x4e8760
    处可执行文件中的代码——它应该是某个函数的
    CALL
    指令。现在找出该函数位于哪个库中,并找到它在库中的地址(通过
    nm
    )。如果幸运的话,那个地址就在
    0xNc56NN
    附近。您现在可以猜测位于
    0x7f0e457NNNNNN
    的任何库的加载地址。重复
    0x7f0e457c55e1
    ,即可在
    0x7f0e442dNNNN
    处找到库的加载地址。
© www.soinside.com 2019 - 2024. All rights reserved.