ARM的自定义堆栈跟踪实现

Custom stacktrace implementation for ARM

本文关键字:跟踪 实现 堆栈 自定义 ARM      更新时间:2023-10-16

我的程序中需要一个用C++编写并在ARM设备上运行的堆栈。我找不到任何可靠的方法来获得starktrace,所以我决定写一个尽可能简单的自己的方法,只是为了在gdb中获得类似stacktrace的东西。

这里有一个想法:编写一个宏来推送FUNCTION__PRETTY_FUNCTION__。有几个问题:

想想我有这样一个宏:

#define STACKTRACE_ENTER_FUNC 
    ... lock mutex
    ... push info into the global list
    ... set scope-exit handler to delete info at function exit
    ... unlock mutex 

现在我需要将这个宏放在代码中的每个函数中。但是他们太多了。有没有更好的方法来实现这个目标,或者我真的应该改变每个函数来包含这个宏:

void foo()
{
    STACKTRACE_ENTER_FUNC;
    ...
}
void bar()
{
    STACKTRACE_ENTER_FUNC;
    ...
}

下一个问题是:我可以使用__PRETTY_FUNCTION__(因为我们只使用固定版本的gcc,而stacktrace实现仅用于在固定平台上调试构建,没有跨平台或编译器问题)。我甚至可以对它进行一点解析,将字符串拆分为函数名和函数参数名。但是,我如何在不了解太多的情况下打印所有函数参数:比如参数的类型或数量?类似:

int foo(char x, float y)
{
     PRINT_ARGS("arg1", "arg2"); // Gives me the string: "arg1 = 'A', arg2 = 13.37"
     ...
}
int main()
{
    foo('A', 13.37);
    ...
}

附言:如果你知道在ARMv6上运行程序时获取堆栈跟踪的更好方法,请告诉我(编译器:arm-openwrt-linux-uclebcgnueabi-gcc 4.7.3,libc:uClibc-0.9.33.2)

提前谢谢。

更简单的解决方案是下拉到汇编-无论如何,C++级别上都不存在堆栈跟踪。

从程序集的角度来看,您使用函数地址的映射(任何链接器都可以生成)。当前指令指针标识顶部帧,返回地址标识调用堆栈。棘手的部分是尾调用优化,这有点哲学(你想要逻辑调用堆栈还是实际调用堆栈?)