【问题标题】:back trace for ulibc in armarm中ulibc的回溯
【发布时间】:2010-10-29 13:21:09
【问题描述】:

我想知道是否有任何移植可用于 arm 中 uclibc 的回溯实现,我可以在我的信号处理程序中使用它来调试分段错误。

我确实遇到了一个有用的代码here 并尝试在我的信号处理程序中使用它,但它在第一次检查时失败并从那里返回。

我还尝试了一个递归回溯函数,它简单地使用 (current_frame_p)-3) 递归直到它为 NULL 并打印 (current_frame_p)-1)。这似乎也给我带来了问题。我得到的只是处理程序的地址和一些垃圾大地址(我假设它可能是信号地址)。但我不会超越这一点。我希望我的追踪能超越这一点。

崩溃的代码是故意编写的,用于调试以取消引用和无效地址。

任何帮助将不胜感激。

非常感谢。

-凯沙夫

【问题讨论】:

    标签: embedded-linux


    【解决方案1】:

    我们在 Arm 设备(不过是 glibc)上使用以下代码。 几年前我发现了这段代码(不记得具体在哪里)。 它运行良好,没有任何问题。

    void __printBacktrace(int skipCount,bool segv=false)
    {
    
    int * func_addresses[BACKTRACE_MAXDEPTH];
    char demangle_output[1000];
    int nfuncs = __arm_backtrace(func_addresses, BACKTRACE_MAXDEPTH );
    printf("-----   Start Stack Trace   -----\n");
    for (int i = skipCount; i < nfuncs; ++i)
    {
        Dl_info info;
        if (dladdr(func_addresses[i], &info))
        {
            int dStat;
            size_t dLength = 1000;
            char * demangled = abi::__cxa_demangle(info.dli_sname,
                    demangle_output, &dLength, &dStat);
            if (demangled && !dStat)
            printf(
                    "return addr: %p: object:%s %p symbol:%s [%p+0x%x]\n",
                    func_addresses[i], info.dli_fname, info.dli_fbase,
                    demangled, info.dli_saddr, (int) func_addresses[i]
                    - (int) info.dli_saddr);
            else
            printf(
                    "return addr: %p: object:%s %p symbol:%s [%p+0x%x]\n",
                    func_addresses[i], info.dli_fname, info.dli_fbase,
                    info.dli_sname, info.dli_saddr, (int) func_addresses[i]
                    - (int) info.dli_saddr);
        } else
        fprintf(fCrash, "return addr: %p\n", func_addresses[i]);
    }
    printf("-----   End Stack Trace -----\n");
    
    
    }
    

    int __arm_backtrace(int **arr, int maxsize)
    
    {
    
        int cnt = 0;
    void *fp = __builtin_frame_address(0);
    struct layout *lp = (struct layout *) ((char*) fp - 12);
    while (cnt < maxsize)
    {
    
        arr[cnt++] = (int *) lp->return_address;
        if (!lp->next)
        {
            break;
        }
        lp = lp->next - 1;
    }
    return cnt;
    }
    

    【讨论】:

    • 非常感谢 Avivl。我会尝试一下,让你知道它是否也适用于 uclibc。
    • 非常感谢 Avivl。我会尝试一下,让你知道它是否也适用于 uclibc。
    • 什么是struct layout,结构的参数是什么?
    【解决方案2】:

    我知道这个问题是关于 uclibc 的,但我现在已经知道如何使用 glibc 进行回溯,所以我想我会说。使用“gcc -funwind-tables -rdynamic”。 unwind-tables 选项使 libc:backtrace() 工作,而 dynamic 选项使 libc:backtrace_symbols() 工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-10
      • 2021-12-28
      • 2018-07-07
      • 2011-07-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多