gcc4.4下实现backtrace代码

来源:互联网 发布:淘宝印度药品代购 编辑:程序博客网 时间:2024/06/03 16:37


   最近在一块新的板子下作开发, 有些变量发生异常(就是我们不想到的值),可以加上backtrace,知道是哪个函数调用它,导致出现异常, 就像死机了,你可以gdb和core文件用bt 命令,查看死机在哪里(有一种 情况 不能看见, 就是发生信号异常不在本文范围  ), 本人感觉还有用, 关说不炼、假把式,下面是实现代码:

   首先实现核心代码backtrace函数:

         

extern void * __libc_stack_end;# define BOUNDED_N(PTR, N) (PTR)#define BOUNDED_1(PTR) BOUNDED_N (PTR, 1)/* Get some notion of the current stack.  Need not be exactly the top   of the stack, just something somewhere in the current frame.  */#ifndef CURRENT_STACK_FRAME# define CURRENT_STACK_FRAME  ({ char __csf; &__csf; })#endif/* By default we assume that the stack grows downward.  */#ifndef INNER_THAN# define INNER_THAN <#endif/* By default assume the `next' pointer in struct layout points to the   next struct layout.  */#ifndef ADVANCE_STACK_FRAME# define ADVANCE_STACK_FRAME(next) BOUNDED_1 ((struct layout *) (((int)next) - 4))#endif/* By default, the frame pointer is just what we get from gcc.  */#ifndef FIRST_FRAME_POINTER# define FIRST_FRAME_POINTER  (__builtin_frame_address (0) - 4)#endifint backtrace (void **array, int size){    struct layout *current;    void *top_frame;    void *top_stack;    int cnt = 0;    top_frame = FIRST_FRAME_POINTER;    top_stack = CURRENT_STACK_FRAME;    /* We skip the call to this function, it makes no sense to record it.  */    current = BOUNDED_1 ((struct layout *) top_frame);    while (cnt < size)    {        if ((void *) current->fp INNER_THAN top_stack                || !((void *) current->fp INNER_THAN __libc_stack_end))        {            /* This means the address is out of range.  Note that for the               toplevel we see a frame pointer with value NULL which clearly is               out of range.  */            break;        }        array[cnt] = current->lr;        cnt++;        current = ADVANCE_STACK_FRAME (current->fp);    }    /*     * In leaf function     * gcc not push lr when call it     */    printf(" ");    return cnt;}

下面就是将她加入一个文件中了

    

/** * @fn          writeToFile * @brief       backtrace写入文件 * @param[in]   *pIndex: 目录 *              *pAppend: 附加信息 * @param[out] * @return      BSTAR_OK    BSTAR_FAIL */int writeToFile(const char *pIndex, const char* pAppend){    int j, nptrs = 0;    void *buffer[100];    char str[1024] = {0};    int fd = 0;    if(NULL == pIndex)    {       fprintf(stderr, "the Index is NULL!\n");       return -1;    }    if((fd = open(pIndex, O_RDWR|O_APPEND, 0644)) < 0)    {        fd = open(pIndex, O_RDWR|O_CREAT|O_APPEND, 0644);    }    nptrs = backtrace(buffer, 100);    if(NULL != pAppend)    {        write(fd, pAppend, strlen(pAppend));        memset(str, 0, 1024);    }    for (j = 0; j < nptrs; j++)    {        sprintf(str, "%p\n", buffer[j]);        write(fd, str, strlen(str));        memset(str, 0, 1024);    }    write(fd, "================\n", strlen("================\n"));    close(fd);    return 0;}

好了,就是这些了, 你可以将她编写成so库, 那样就方便调用了

原创粉丝点击