我在ARM处理器上运行FreeRTOS并且我没有dump_stack()可用于我...我正在尝试检查调用链并严重丢失dump_stack()...我在google搜索了一下,发现了一些关闭的东西我正在寻找,使用GCC(/ GDB)_Unwind_Backtrace()实用程序,但它只打印stack_frame的地址。它不提供映射到有意义的符号(如函数名称)。任何帮助都非常感谢。
#include <stdio.h>
#include <unwind.h>
#include <stdint.h>
static _Unwind_Reason_Code unwind_backtrace_callback(struct _Unwind_Context* context, void* arg)
{
uintptr_t pc = _Unwind_GetIP(context);
if (pc) {
printf("unwind got pc ...0x%x\n", pc);
}
return _URC_NO_REASON;
}
ssize_t unwind_backtrace()
{
_Unwind_Reason_Code rc = _Unwind_Backtrace(unwind_backtrace_callback, 0);
return rc == _URC_END_OF_STACK ? 0 : -1;
}
void func_1()
{
int ret = unwind_backtrace();
printf("unwind_backtrace return ...%d\n", ret);
}
void func_2()
{
func_1();
}
int main()
{
func_2();
return 0;
}
Result:
unwind got pc ...0x40076b
unwind got pc ...0x400796
unwind got pc ...0x4007bd
unwind got pc ...0x400819
unwind got pc ...0x67314b15
unwind got pc ...0x400649
unwind_backtrace return ...0
我使用的所有IDE(我使用了很多)向我展示了窗口中的堆栈跟踪 - 但仅适用于当前正在执行的任务。如果我想查看所有任务的跟踪,我需要一个完全线程感知的FreeRTOS插件,该插件由Segger,IAR和Code Confidence提供。
它不提供有意义符号的映射
执行此映射的“标准”方法是使用addr2line。就像是:
addr2line -fe a.out 0x40076b 0x400796 0x4007bd ...
更新:
我想要飞行转换......
那么,你应该问过那个问题。
编写代码很简单。您需要编写将地址范围映射到符号名称的代码(就像addr2line
一样)。
在ELF平台上,这实际上非常简单:从Elf32_Sym
部分读取.symtab
s以构建地址到符号映射,并在该映射中查找地址。您还需要从.strtab
部分读取相应的符号名称(Elf32_Sym.st_name
是.strtab
的偏移量)。