Linux下利用backtrace追踪函数调用堆栈以及定位段错误

太理论我也说,主要就是下面这两个函数,打印栈地址, 下面的程序流程就是接受段错误的信号,调用信号函数,信号函数就是下面2个函数,打印栈的地址

编译时类似这样gcc -g -rdynamic test.c -o test; ./test  也就是要有-g -rdynamic 参数,  然后使用addrline 命令。

addr2line 0x80486ad -e ./a.out f   然后就会出现函数名字和行数

在信号函数下面函数就是出现错误的函数。你也可以

使用objdump -d test > test.s   查看汇编代码。

score:./exe(_Z4dumpi+0x5e) [0x8048a92]
score:[0x74d420
score:./exe(_Z5fun_cv+0x10) [0x8048966]
score:./exe(_Z5fun_bv+0xb) [0x804898f]
score:./exe(_Z5fun_av+0xb) [0x80489a1]
score:./exe(main+0x40) [0x8048b3a]
score:/lib/libc.so.6(__libc_start_main+0xdc) [0x812e9c]
score:./exe(__gxx_personality_v0+0x45) [0x8048831]

        int size = backtrace(back_p, sizeof(back_p));score:./exe(_Z4dumpi+0x5e) [0x8048a92]
        printf ("size =%d\n", size);
        stack_info = backtrace_symbols(back_p, size);



#include "execinfo.h"



int add(int a, int b);


int fun_a();
int fun_b();
int fun_c();
void dump(int signal);


int a;


int main()
{
        if (signal(SIGSEGV, dump) == SIG_ERR)
                perror("cat 't  catch SIGSEGV");
        fun_a();
        return 0;
}
void dump(int signal)
{
        a++;
        printf("dump is called %d times\n", a);
        void *back_p[20] = {0};
        char **stack_info = NULL;


        int size = backtrace(back_p, sizeof(back_p));
        printf ("size =%d\n", size);
        stack_info = backtrace_symbols(back_p, size);


        for (int i = 0; i < size; i++)
                printf("score:%s\n", stack_info[i]);
        exit(0);
}


                
        for (int i = 0; i < size; i++)
                printf("add {score:%s}\n", stack_info[i]);
        return a+b;
}
int fun_a()
{
        fun_b();
        return 0;
}


int fun_b()
{
        fun_c();
        return 0;
}


int fun_c()
{
        char * p = NULL;
        printf("%d|n", *p);
        return 0;
}

你可能感兴趣的:(c++,项目源码学习)