How to use addr2line
addr2line 是 GNU Binutils 提供的一个调试工具,用于将程序地址转换为源代码文件 + 行号。
其底层依赖 ELF 文件中的 DWARF 调试信息。
典型使用场景:
- core dump 分析
- 崩溃栈回溯解析
- 日志中只有地址信息
- 线上二进制与调试符号分离
示例分析
例如某崩溃日志中看到:
1 | .../your_binary(_ZN19MyTableC1EPS_+0x10d)[0x1f792fd] |
含义:
- ZN19MyTableC1EPS → C++ mangled 名字
- +0x10d → 相对于函数起始地址的偏移
- [0x1f792fd] → 实际程序地址
如果符号信息在可执行文件上
1
addr2line -e your_binary -f -C 0x1f792fd
use eu-addr2line 加载symbol
1
eu-addr2line -e ./your_binary --debuginfo-path=./your_binary.debug 0x1f792fd
output:
mytable/MyTable.cpp:1070只有函数名 + 偏移
例如日志只有: MyTable::insert+0x52
需要手动计算地址。- 查函数起始地址
1
nm -C your_binary | grep my_func
或如果 binary 已 strip,需要对 debug 文件执行 nm:
假设得到:1
objdump -t your_binary | grep MyTable::insert
1
0000000000401230 T MyTable::insert
- 加上偏移
1
0x401230 + 0x52 = 0x401282
- 再 addr2line
1
addr2line -e your_binary -f -C 0x401282
- 查函数起始地址
PIE / ASLR 注意事项
如果二进制是 PIE(Position Independent Executable):
1 | readelf -h your_binary | grep Type |
如果看到:
1 | Type: DYN (Position-Independent Executable file) |
说明是 PIE。
这时:
崩溃日志中的地址 = load_base + offset
必须减去加载基地址
在 core dump 中:
1 | info proc mappings |
或者
1 | cat /proc/<pid>/maps |
找到加载基址,例如:
1 | 7f3c2d400000-... |
再传给 addr2line。
否则会解析失败或定位错误。
常用排错检查
是否包含调试信息
1
readelf --sections your_binary | grep debug
是否被 strip
1
file your_binary