产生的原因:访问没有权限或没有存在的内存
目的:可以缩小定位错误的范围
#include <stdio.h>
#include <signal.h>
#include <execinfo.h>
#include <stdlib.h> // 缺失这个call trace 信息会丢失
void func_a(int a);
void func_b(int b);
void func_c(int c);
void DebugBacktrace(void);
void func_a(int a)
{
printf("%d: A call B\n", a);
func_b(2);
}
void func_b(int b)
{
printf("%d: B call C\n", b);
func_c(3); /* 这个函数调用将导致段错误 */
}
void func_c(int c)
{
char *p = (char *)c;
*p = 'A'; /* 如果参数c不是一个可用的地址值,则这条语句导致段错误 */
printf("%d: function C\n", c);
}
/* SIGSEGV信号的处理函数,回溯栈,打印函数的调用关系 */
void DebugBacktrace(void)
{
#define SIZE 100
void *array[SIZE];
int size, i;
char **strings;
fprintf (stderr, "\nSegmentation fault\n");
size = backtrace (array, SIZE);
fprintf (stderr, "Backtrace (%d deep):\n", size);
strings = backtrace_symbols (array, size);
for (i = 0; i < size; i++)
fprintf (stderr, "%d: %s\n", i, strings[i]);
free (strings);
exit(-1);
}
int main(int argc, char **argv)
{
char a;
/* 设置SIGSEGV信号的处理函数 */
signal(SIGSEGV, DebugBacktrace);
func_a(1);
return 0;
}
CC=aarch64-none-linux-gnu-gcc
CFLAGS=-g -O0
LDFLAGS=-rdynamic
segfault: segfault.o
$(CC) $(LDFLAGS) -o $@ $^
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $^
clean:
rm -f segfault *.o
/mnt/segfault # ./segfault
1: A call B
2: B call C
Segmentation fault
Backtrace (8 deep):
0: ./segfault(DebugBacktrace+0x3c) [0x400cec]
1: linux-vdso.so.1(__kernel_rt_sigreturn+0) [0x7fb0503658]
2: ./segfault(func_c+0x1c) [0x400c90]
3: ./segfault(func_b+0x24) [0x400c68]
4: ./segfault(func_a+0x24) [0x400c38]
5: ./segfault(main+0x28) [0x400db4]
6: /lib64/libc.so.6(__libc_start_main+0xe0) [0x7fb037da60]
7: ./segfault(_start+0x50) [0x400b50]