如何在Linux中使用addr2line命令?

发布于 2024-12-08 12:17:06 字数 181 浏览 0 评论 0原文

我尝试在 Unix 中使用 addr2line 命令,但每次它都会给出与 ??:0 相同的输出。我给出的命令为 addr2line -e a.out 0x4005BDC 。我在使用 valgrind 工具运行 a.out 可执行文件以查找内存泄漏时获得了此地址。我还使用 -g 选项编译了源代码。

I am trying to use addr2line command in Unix but everytime it is giving the same output as ??:0. I am giving command as addr2line -e a.out 0x4005BDC . I got this address while running this a.out executable with valgrind tool to find the memory leakage. I also compiled the source code with -g option.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

手心的海 2024-12-15 12:17:06

您还可以使用 gdb 而不是 addr2line 来检查内存地址。在 gdb 中加载可执行文件并打印存储在该地址处的符号的名称。 16 检查符号表

(gdb) info symbol 0x4005BDC 

You can also use gdb instead of addr2line to examine memory address. Load executable file in gdb and print the name of a symbol which is stored at the address. 16 Examining the Symbol Table.

(gdb) info symbol 0x4005BDC 
静谧幽蓝 2024-12-15 12:17:06

您需要指定 addr2line 的偏移,而不是虚拟地址 (VA)。据推测,如果您关闭了地址空间随机化,则可以使用完整的 VA,但在大多数现代操作系统中,地址空间会针对新进程进行随机化。

给定 valgrind 的 VA 0x4005BDC,找到内存中进程或库的基地址。通过在程序运行时检查 /proc//maps 文件来完成此操作。感兴趣的行是进程的 text 段,可以通过权限 r-xp 以及程序或库的名称来识别。

假设基本 VA 为 0x0x4005000。然后你会发现 valgrind 提供的 VA 和基本 VA 之间的差异:0xbdc。然后,将其提供给 add2line:

addr2line -e a.out -j .text 0xbdc

看看是否可以获取行号。

You need to specify an offset to addr2line, not a virtual address (VA). Presumably if you had address space randomization turned off, you could use a full VA, but in most modern OSes, address spaces are randomized for a new process.

Given the VA 0x4005BDC by valgrind, find the base address of your process or library in memory. Do this by examining the /proc/<PID>/maps file while your program is running. The line of interest is the text segment of your process, which is identifiable by the permissions r-xp and the name of your program or library.

Let's say that the base VA is 0x0x4005000. Then you would find the difference between the valgrind supplied VA and the base VA: 0xbdc. Then, supply that to add2line:

addr2line -e a.out -j .text 0xbdc

And see if that gets you your line number.

肤浅与狂妄 2024-12-15 12:17:06

这正是您使用它的方式。不过,您拥有的地址有可能与源代码中的某些内容不直接对应。

例如:

$ cat t.c
#include <stdio.h>
int main()
{
    printf("hello\n");
    return 0;
}
$ gcc -g t.c
$ addr2line -e a.out 0x400534
/tmp/t.c:3
$ addr2line -e a.out 0x400550
??:0

在我的例子中,0x400534main的地址。 0x400408也是a.out中的有效函数地址,但它是由GCC生成/导入的一段代码,没有调试信息。 (在本例中,__libc_csu_init。您可以使用 readelf -a your_exe 查看可执行文件的布局。)

addr2line 失败的其他情况是如果您包含一个没有调试信息的库。

That's exactly how you use it. There is a possibility that the address you have does not correspond to something directly in your source code though.

For example:

$ cat t.c
#include <stdio.h>
int main()
{
    printf("hello\n");
    return 0;
}
$ gcc -g t.c
$ addr2line -e a.out 0x400534
/tmp/t.c:3
$ addr2line -e a.out 0x400550
??:0

0x400534 is the address of main in my case. 0x400408 is also a valid function address in a.out, but it's a piece of code generated/imported by GCC, that has no debug info. (In this case, __libc_csu_init. You can see the layout of your executable with readelf -a your_exe.)

Other times when addr2line will fail is if you're including a library that has no debug information.

嗼ふ静 2024-12-15 12:17:06

尝试添加 -f 选项来显示函数名称:

addr2line -f -e a.out 0x4005BDC

Try adding the -f option to show the function names :

addr2line -f -e a.out 0x4005BDC
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文