前情
上一篇笔记《异常信息转储预研笔记-堆栈地址转换》留下了两个待解决问题(如下图),问题1已在《异常信息转储笔记-demangle函数名字符》中解决,剩下问题2输出源码行号的问题还未能解决。
之前使用dladdr并未能将堆栈地址转换成源码行号,说明此路不通。
本文将尝试其他方案,成功与否,效果如何,将一一在此记录。
需求描述
在整个core信息转存下来的过程中,对实际应用中调试、定位和分析问题来说,最直观的就是根据堆栈调用中的函数名和源码行号来定位程序执行情况。
目前,已经成功输出了每个栈帧的指令地址、栈地址、函数名和寄存器状态等信息,独缺源文件行号。
待验证方案
根据了解,目前已知可能存在的方案有如下三个:
方案1、使用popen管道执行addr2line命令;
方案2、elfutils/libdwfl.h库中的dwfl_lineinfo方法;
方案3、GNU binutils中libbfd库;
验证过程
方案1
写了个demo,验证发现输出是??:0,可能原因是addr2line命令参数需要的是偏移地址,而不是栈帧的指令指针地址。
偏移地址需要计算,过程略复杂。
方案2
由于此方案需要编译安装三方库,故选择放在最后验证,看完方案1和3,没想到方案2是最后的救命稻草了。
项目官方地址:The elfutils project (sourceware.org)
先下载源码包吧。
下载完成,进入elfutils的源码;
运行配置脚本:./configure --disable-libdebuginfod --disable-debuginfod
编译安装:make && make install
默认应该会安装在/usr/local/下,安装完可以在/usr/local/include下确认一下有没有elfutils相关文件。
安装完上测试demo:
编译参数别忘了添加-ldw来链接libdw库;
经测试,方案可行;
但是不知道为啥,一些基础库能显示文件名和行号,但是自己编的代码却不显示。
方案3
经过了解,发现libbfd库主要对二进制文件进行操作,并不符合当前需求。
整个垮掉了。
题外
目前除了已知的libunwind和google的coredumper项目,还有boost似乎也提供stacktrace。