2011-12-17 101 views
23

我有一个精简应用程序,它看起来像这样产生的堆栈跟踪:使用gdb进行地址转换为线

*** 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

这我假设是因为该地址在共享库中的一个,但怎么也我知道他们中的哪一个?

+3

['addr2line'](http://linuxcommand.org/man_pages/addr2line1.html)? – 2011-12-17 16:10:27

+0

@ another.anon.coward Year,我试过,但我不知道如何查找哪个文件,因为地址指向共享库。 – Allan 2011-12-17 17:24:07

+0

@Allan:您可以使用'info sharedlibrary'命令来知道哪个共享库的地址为0x7f0e442d801d。 – ks1322 2011-12-17 19:00:57

回答

25

但我怎么能翻译地址转换成文件和行号?

对于主要的可执行文件(如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找出库的加载地址。
17

%的OP,在GDB的命令从地址找到的代码的源代码行是:

info line *0x10045740 

编辑:替换“信息符号0x10045740”,不会在某些工作条件(谢谢@ Thomasa88)。

+3

这只在/ home/thomas/.kde4/lib64/kde4/kmm_lft.so'节的.text节中显示符号+ offset('LftPlugin :: import_clicked()const + 1522),而'info line * 0xabc'显示(“plugin/lft_plugin.cpp”的第97行开始于地址0x7fffe49eb39c 并结束于0x7fffe49eb3ad .')。在我的情况下,我的共享库没有被剥离,但是当符号被剥离时,“add-symbol-file filename address”可能会有帮助。 http://www.delorie.com/gnu/docs/gdb/gdb_125.html – thomasa88 2015-01-02 18:47:37

+3

谢谢thomasa88! 'gdb中的信息行* 0x10045740'(记得星号)完成这项工作。 – 2015-01-21 11:18:52