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
Using gdb to convert addresses to lines
提问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 CALL
instruction) from all of the above addresses.
实际上,您可能希望从上述所有地址中减去5
(CALL
指令的通常长度)。
For the addresses in shared libraries, you have to know the load address of the library.
对于共享库中的地址,您必须知道库的加载地址。
If your application produced a core
file, then (gdb) info shared
will 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 aCALL
instruction to some function. Now find out which library that function is in, and find its address in the library (vianm
). If you are lucky, that address is near0xNc56NN
. You can now guess the load address of whatever library is at0x7f0e457NNNNNN
. Repeat for0x7f0e457c55e1
, and you can find out the load address of library at0x7f0e442dNNNN
.
- 您应该修复应用程序,以便它打印该信息(没有它,堆栈跟踪几乎没有用),并且
- 您仍然可以猜测:查看可执行文件中的代码
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)。