linux addr2line
程序员文章站
2022-05-27 22:52:26
...
addr2line 命令可以在程序core时,提供一种辅助手段定位程序问题。
下面演示除零错误:
#include <stdio.h> int main(int argc, char **argv) { int x = 10; int y = 0; printf("%d/%d=%d\n", x, y, x/y); return 0; }
程序执行后立即退出,可查看系统dmesg日志:
$ ./test Floating point exception (core dumped) $ dmesg [15222401.075980] traps: test[26231] trap divide error ip:400611 sp:7ffcdb1f0290 error:0 in test[400000+1000] $ addr2line -e test 400611 /data/home/kanesun/test/test.c:7
addr2line显示第7行除零错误。程序需要加-g编译debug版本才行,否则命令无法显示行:??:?,因为addr2line是通过查找调试信息定位到行的。
DWARF(Debugging With Attributed Record Formats)调试格式记录了程序调试信息,其中.debug_line记录了程序地址与源代码行对应关系。
$ readelf -w test Line Number Statements: Extended opcode 2: set Address to 0x4005f0 Special opcode 8: advance Address by 0 to 0x4005f0 and Line by 3 to 4 Special opcode 216: advance Address by 15 to 0x4005ff and Line by 1 to 5 Special opcode 104: advance Address by 7 to 0x400606 and Line by 1 to 6 Special opcode 104: advance Address by 7 to 0x40060d and Line by 1 to 7 Advance PC by constant 17 to 0x40061e Special opcode 216: advance Address by 15 to 0x40062d and Line by 1 to 8 Special opcode 76: advance Address by 5 to 0x400632 and Line by 1 to 9
二进制编码从0x4005ff开始,0x40062d对应第8行,则0x400611对应第7行。
线上监控发现程序有重启,但是没有开启coredump,查看dmesg,发现有打印:
[2157427.236306] traps: flowmonitor[158426] general protection ip:409445 sp:7f519cb3d450 error:0 in flowmonitor[400000+be000]\ addr2line -e flowmonitor 409445 /usr/include/c++/4.8.2/bits/stl_list.h:235
查看stl源码:
_List_const_iterator(const iterator& __x) : _M_node(__x._M_node) { } _Self& operator++() { _M_node = _M_node->_M_next; // 出错行 return *this; }
获取list const迭代器下一个节点时出错,可能是该迭代器被清除了,直接访问下一个node会出错。 可是flowmonitor 程序中没有操作std::list 的常量迭代器,发现依赖的rdkafka 接口有std::list 使用,此时通过lsof查看程序的网络连接,发现只有一个连接,与运营同学沟通发现果然是kafka集群出问题了。 addr2line 提供了线上排障提供更多的一个选择。