有没有适用于uclibc的backtrace移植版?

10
我们正在ARM 9上运行uclibc linux。问题是uclibc不支持回溯。当出现核心转储时,无法获取调用堆栈。有没有好的解决方案?例如,为uclibc现有的回溯移植,或任何在核心转储发生时抓取调用堆栈的好方法(uclibc+ ARM + Linux)?
2个回答

5

更新:

似乎已经创建了一个修补程序,用于支持x86和ARM(XScale)上uclibc的backtrace()函数,并利用了__libc_stack_end符号。


原始回答:

我曾经参与了一个项目,我们使用的glibc版本没有为我们的ARM处理器提供功能完整的backtrace()函数,因此我们在glibc之外开发了自己的代码,使用了__libc_stack_end符号。下面是最终的代码。也许你可以用它来编写uclibc的backtrace()函数。

extern void * __libc_stack_end;

struct backtrace_frame_t
{
    void * fp;
    void * sp;
    void * lr;
    void * pc;
};

int backtrace(void ** array, int size)
{
    void * top_frame_p;
    void * current_frame_p;
    struct backtrace_frame_t * frame_p;
    int frame_count;

    top_frame_p = __builtin_frame_address(0);
    current_frame_p = top_frame_p;
    frame_p = (struct backtrace_frame_t*)((void**)(current_frame_p)-3);
    frame_count = 0;

    if (__builtin_return_address(0) != frame_p->lr)
    {
        fprintf(stderr, "backtrace error: __builtin_return_address(0) != frame_p->lr\n");
        return frame_count;
    }

    if (current_frame_p != NULL
        && current_frame_p > (void*)&frame_count
        && current_frame_p < __libc_stack_end)
    {
        while (frame_count < size
               && current_frame_p != NULL
               && current_frame_p > (void*)&frame_count
               && current_frame_p < __libc_stack_end)
        {
            frame_p = (struct backtrace_frame_t*)((void**)(current_frame_p)-3);
            array[frame_count] = frame_p->lr;
            frame_count++;
            current_frame_p = frame_p->fp;
        }
    }

    return frame_count;
}

注意:在较新版本的glibc中,不再导出__libc_stack_end符号,我不确定uclibc中是否存在它或类似的符号。

从上述代码中,我得到了运行时错误“backtrace error: __builtin_return_address(0) != frame_p->lr”。如何解决这个问题。 - Mandar
标准的ARM调用约定(pdf链接)将r14分配为链接寄存器。在子程序调用中使用的BL指令将返回地址存储在该寄存器中。__builtin_frame_address(0)__builtin_return_address(0)函数用于获取调用函数的返回和帧地址。您的错误提示称链接寄存器不包含返回地址,或者backtrace_frame_t结构与堆栈帧不匹配。 - jschmier

1

你应该将那篇帖子中的信息放入你的回答中,否则当链接失效时,你的回答就变得无用了。 - George Stocker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接