太理论我也说,主要就是下面这两个函数,打印栈地址, 下面的程序流程就是接受段错误的信号,调用信号函数,信号函数就是下面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;
}