我们在ARM 9上运行uclibc linux。问题是uclibc不支持backtrace。当发生核心转储时,我无法获取调用堆栈。

有人对此有好的解决方案吗?

例如,是否已有uclibc的backtrace移植,或者在发生核心转储时是否有任何好的方法来捕获调用堆栈(uclibc + ARM + Linux)?

最佳答案

更新:

似乎创建了 patch 以在uclibc上为x86和ARM(XScale)支持backtrace(),并且它使用了__libc_stack_end符号。

原始答案:

我在一个项目中工作,该项目所使用的glibc版本没有为我们的ARM处理器提供功能的backtrace(),因此我们使用__libc_stack_end符号在glibc之外开发了自己的代码。下面是结果代码。也许您可以使用它来编写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;
}

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

关于linux - uclibc的backtrace有任何移植可用吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2536021/

10-10 17:43