Linux 使用 gdb 将地址转换为行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8545931/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 03:41:56  来源:igfitidea点击:

Using gdb to convert addresses to lines

clinuxgdb

提问by Allan

I have a stack trace generated by a stripped application which looks like this:

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

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

And I have a non-stripped version of the executable and all of its libraries ( compiled with debug information). But how can I translate the address into files and line numbers??

我有一个非剥离版本的可执行文件及其所有库(使用调试信息编译)。但是如何将地址转换为文件和行号??

Here is what I have tried:

这是我尝试过的:

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

When I type in the file command it only loads symbols from the file, not all the libraries which are used. Is there a way this can be done?

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

The "info line" command says:

“信息行”命令说:

No line number information available for address 0x7f0e442d801d

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

Which I assumes is because the address is in one of the shared libraries, but how can I know in which one of them?

我假设是因为地址在共享库之一中,但是我怎么知道在其中一个中?

采纳答案by Employed Russian

But how can I translate the address into files and line numbers?

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

For the main executable (addresses like 0x4e8765) do this:

对于主要的可执行文件(地址如0x4e8765),请执行以下操作:

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

Actually, you might want to subtract 5(usual length of the CALLinstruction) from all of the above addresses.

实际上,您可能希望从上述所有地址中减去5CALL指令的通常长度)。

For the addresses in shared libraries, you have to know the load address of the library.

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

If your application produced a corefile, then (gdb) info sharedwill tell you where libraries were loaded.

如果您的应用程序生成了一个core文件,那么它(gdb) info shared会告诉您库的加载位置。

If you did not get a core file, and the application did not print the required mapping, then

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

  • you should fix the application so it does print that info (the stack trace is mostly useless without it), and
  • you could still guess: look at the code in the executable at 0x4e8760-- it should be a CALLinstruction to some function. Now find out which library that function is in, and find its address in the library (via nm). If you are lucky, that address is near 0xNc56NN. You can now guess the load address of whatever library is at 0x7f0e457NNNNNN. Repeat for 0x7f0e457c55e1, and you can find out the load address of library at 0x7f0e442dNNNN.
  • 您应该修复应用程序,以便它打印该信息(没有它,堆栈跟踪几乎没有用),并且
  • 您仍然可以猜测:查看可执行文件中的代码0x4e8760- 它应该是CALL某个函数的指令。现在找出该函数在哪个库中,并在库中找到它的地址(通过nm)。如果幸运的话,那个地址就在附近0xNc56NN。您现在可以猜测任何库的加载地址0x7f0e457NNNNNN。重复0x7f0e457c55e1,可以在 处找到库的加载地址0x7f0e442dNNNN

回答by whitey04

Per the OP, the command in GDB to find the source line of code from an address is:

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

info line *0x10045740

Edit: Replaced "info symbol 0x10045740" which won't work under certain conditions (thanks @Thomasa88).

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