在默认情况下,addr2line 只输出源码文件名和行号,要同时查看函数名,需要加上专门的选项。最常用的是 -f(或 --functions)显示函数名,再配合 -C(或 --demangle)对 C++ 符号进行解混淆;也可使用 -p(或 --pretty-print)将地址、函数名、文件名和行号合并到一行输出。下面详细介绍各选项及示例,并补充其他定位函数名的方法。

一、addr2line 查看函数名的选项

1. -f / --functions

添加此选项后,addr2line 会在每个 FILENAME:LINENO 之前额外输出一行包含函数名的 FUNCTIONNAME,即所属函数的名称 (addr2line(1) - Linux manual page)。

2. -C / --demangle[=style]

对 C++ 符号进行解混淆(demangle),将低级别的符号名还原为可读的用户级函数名。可选的 style 参数用于指定不同编译器的混淆风格 (addr2line(1) - Linux manual page)。

3. -p / --pretty-print

将地址、函数名、文件名和行号合并为一行,更易于阅读;若同时使用 -i,则内联函数会另起行并带上 (inlined by) 前缀 (addr2line(1) - Linux manual page)。

4. 其他常用选项

二、丰富示例

示例 1:简单可执行文件中查看函数名

gcc -g test.c -o test        # 加 -g 保留调试信息  
addr2line -f -C -e test 0x4005BDC

输出示例:

main  
/home/user/test.c:42

(How to use the addr2line command in Linux? - Stack Overflow)

示例 2:同时查询多个地址

printf "0x4005BDC\n0x4005C10" | addr2line -f -C -e test

示例 3:共享库中查询

addr2line -f -C -e /lib/libc.so.6 0x28980 0x1ac46

可得函数名和源码位置 (linux - How to find out function name in libc.so - Stack Overflow)。

示例 4:漂亮输出

addr2line -p -f -C -e test 0x4005BDC

三、其他定位函数名的方法

1. 使用 GDB

gdb -q test  
(gdb) info symbol 0x4005BDC    # 等价于 addr2line -f

或用 x/i 反汇编查看所在函数上下文 (linux - How to find out function name in libc.so - Stack Overflow)。

2. 使用 eu-addr2line(elfutils)

eu-addr2line -Ci -e test 0x... 同样支持 -C-i 等选项,但历史上曾有 -Ci 识别问题已修复 (2182059 – eu-addr2line -i option to display inlined functions doesn't ...)。

四、注意事项

  • 必须-g 编译生成调试信息,否则 addr2line 会输出 ??:0 (addr2line Command in Unix - Tutorialspoint)。
  • 不要对已 strip 的二进制或库运行,否则同样无法解析符号。
  • C++ 代码强烈建议同时加 -C 以获得可读函数名。