arm uclibc中实现backtrace

在arm中很多平台并无法使用gclibc环境,无法使用gclibc给出的backtrace,在这种情况下如果应用程序出错,出现段错误等情况,无法准确的定位出段错误的根源,经过研究之后终于折腾出了适用于uclibc环境中的dumpstack方法


#include <sys/time.h>
#include <sys/resource.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ucontext.h>
#include <signal.h>
#include <dlfcn.h>


typedef struct
{
    const char *dli_fname;  /* File name of defining object.  */
    void *dli_fbase;        /* Load address of that object.  */
    const char *dli_sname;  /* Name of nearest symbol.比如函数名*/
    void *dli_saddr;        /* Exact value of nearest symbol.比如函数的起始地址*/
} Dl_info;


struct ucontext_ce123 {
    unsigned long     uc_flags;
    struct ucontext  *uc_link;
    stack_t       uc_stack;
    struct sigcontext uc_mcontext;
    sigset_t      uc_sigmask;   /* mask last for extensibility */
}ucontext_ce123_;


struct sigframe_ce123 {
    struct sigcontext sc;//保存一组寄存器上下文
    unsigned long extramask[1];
    unsigned long retcode;//保存返回地址
    //struct aux_sigframe aux __attribute__((aligned(8)));
}sigframe_ce123;


void dumpstack()
{


    Dl_info info;
    int status;


    int *fp = 0, *next_fp = 0;
    int cnt = 0;
    int ret = 0;


    __asm__(
        "mov %0, fp\n"
        : "=r"(fp)
    );




    next_fp = (int *)(*(fp-3));
    while(next_fp != 0)
    {
        void * pcur = (void *)*(next_fp - 1);


        status = dladdr (pcur, &info);
        if (status && info.dli_fname && info.dli_fname[0] != '\0')
        {
            printf("0x%08x 0x%08x %-20s <  %s+%p  >\r\n",pcur,info.dli_saddr,info.dli_fname,info.dli_sname,(unsigned long)((unsigned int)pcur - (unsigned int)info.dli_saddr));
        }
        else
         {
            printf ( "[%p]", (void *)*(next_fp - 1));
         }


        //array[cnt++] = (void *)*(next_fp - 1);
        next_fp = (int *)(*(next_fp-3));
        cnt++;
    }

    printf("Backstrace (%d deep)\n", cnt);
}


在arm-linux-gcc编译需要加入参数-ldl -rdynamic使得编译通过


使用方法:

static void my_sighdlr (int sig)
{
if (sig == SIGSEGV)
        { // Ignore SIGPIPE.
   dumpstack();
                return;
        }
go = 0;
}

int testfun(int n)

{

dumpstack();

if(n>=10)

{

memset(0,0,100);

}

testfun(n++);

}
int main()
{
signal(SIGSEGV, my_sighdlr);

testfun(0);

return 0;
}



  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值