有没有比使用backtrace()更便宜的方法来查找调用堆栈的深度?

我的日志代码使用返回值backtrace()来确定当前的堆栈深度(用于漂亮的打印目的),但我可以从分析中看到这是一个相当昂贵的调用.

我不认为有更便宜的方法吗?请注意,我不关心帧地址,只有它们有多少.

编辑:这些日志记录功能遍布大型代码库,因此手动跟踪堆栈深度并不是一种选择.

解决方法:

自己走栈很快 – 回溯()的大部分缓慢来自于查找符号名称.在x86上,您可以执行以下操作:

inline uint32_t get_ebp(void)
{
    __asm__ __volatile__("mov %%ebp, %%eax");
}

int get_stack_depth(void)
{
    uint32_t ebp = get_ebp();
    int stack_depth = 0;
    while(ebp != 0)
    {
        ebp = *(uint32_t *)ebp;
        stack_depth++;
    }
    return stack_depth;
}

这将走向ebp指针链.请记住,这是非常不便携的.另请注意,这不会计算任何内联或尾调用优化的函数(当然,backtrace()也有同样的问题).

另一个重要的问题是终止条件 – 一旦你回溯到main(),通常不能保证你在堆栈中找到什么.因此,如果libc没有放置空帧指针,那么很可能是段错误.您可以在main()的最开头查看终止值.

上一篇:如何在C中手动迭代堆栈帧?


下一篇:python backtrace注意事项