linux移植cm_backtrace
问题背景
- appserver使用了backtrace接口来跟踪程序死机崩溃的调用栈,得到死机的现场信息
- 当程序挂死在strlen中(strlen(NULL)),无法定位到是谁调用的strlen
问题分析
- 已经定位到是因为backtrace需要程序支持FP指针(栈帧),而strlen在C库中并没有使用FP指针,导致backtrace无法追踪strlen的上一层调用
- glibc在正常方案中不会使用FP指针(需要重新编译C库,并且影响运行效率),所以backtrace使用FP指针追踪调用栈不是一个好方法
- 在小核中,也有同样的获取调用栈的工具:cm_backtrace,该工具并没有依赖于FP指针,也可以追踪调用栈
- 小核(cortex-m3)和大核(cortex-a7)均为ARMv7指令集,可以尝试移植cm_backtrace到大核中,看能否成功获取调用栈
实现过程
实验1
cm_backtrace原理分析
CmBacktrace (Cortex Microcontroller Backtrace)是一款针对 ARM Cortex-M 系列 MCU 的错误代码自动追踪、定位,错误原因自动分析的开源库。
- 根据错误现场状态,输出对应的 线程栈 或 C 主栈;
- 适配 Cortex-M0/M3/M4/M7 MCU;
- 支持 IAR、KEIL、GCC 编译器;
cm_backtrace可以支持多种编译器,并不像c库里的backtrace函数依赖于FP指针的编译参数,对于所有的编译器和优化选项都可以通用
分析cm_backtrace源码,其实现原理十分简单:
- 从栈顶(低地址)开始,按出栈的方向(cortex-m的压栈顺序是从高地址往低地址压),遍历栈内的内容,按4字节读取
- 判定压入栈的内容是否为代码地址空间,若是则读取该代码空间地址的指令
- 判断该代码地址的代码指令是否为跳转指令(BL或BLX),即发生了函数调用,记录下该代码地址空间
- 由此遍历完整个栈空间,直到栈底,即可推导出整个栈内函数调用关系
两个关键函数:
/* check the disassembly instruction is 'BL' or 'BLX' */
static bool disassembly_ins_is_bl_blx(uint32_t addr);
/**
* backtrace function call stack
*
* @param buffer call stack buffer
* @param s

最低0.47元/天 解锁文章
5107

被折叠的 条评论
为什么被折叠?



