linux addr2line

阅读更多

 

    addr2line 命令可以在程序core时,提供一种辅助手段定位程序问题。

 

   下面演示除零错误:

#include 

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 提供了线上排障提供更多的一个选择。

 

 

 

 

 

你可能感兴趣的:(addr2line,DWARF)