使用backtrace和backtrace_symbols追蹤段錯
阿新 • • 發佈:2019-02-16
結合文章http://blog.csdn.net/zahuopuboss/article/details/46519697
與訊號處理
在程式出現段錯的時候,列印函式呼叫鏈
#include <execinfo.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> void trace(int signo) { int j, nptrs; #define SIZE 100 void *buffer[100]; char **strings; printf("signo: %d\n", signo); nptrs = backtrace(buffer, SIZE); printf("backtrace() returned %d addresses\n", nptrs); /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO) * would produce similar output to the following: */ strings = backtrace_symbols(buffer, nptrs); if (strings == NULL) { perror("backtrace_symbols"); exit(EXIT_FAILURE); } for (j = 0; j < nptrs; j++) printf("%s\n", strings[j]); free(strings); if (SIGSEGV == signo || SIGQUIT == signo) { exit(0); } } void segfault(void) { int *p = NULL; *p = 1; } int main(int argc, char *argv[]) { signal(SIGSEGV, trace); signal(SIGINT, trace); signal(SIGQUIT, trace); while (1) { sleep(1); if (time(0) % 7 == 0) { segfault(); } } return 0; }
編譯方法 gcc -rdynamic seg.c -o seg -g
段錯資訊
signo: 11
backtrace() returned 6 addresses
./seg(trace+0x3c) [0x400aac]
/lib64/libc.so.6() [0x3c39635690]
./seg(segfault+0x10) [0x400b64]
./seg(main+0x83) [0x400bef]
/lib64/libc.so.6(__libc_start_main+0xf5) [0x3c39621b45]
./seg() [0x4009a9]
使用 objdump -d seg 查看出錯地址 0x400b64 是一個賦值操作
0000000000400b54 <segfault>: 400b54: 55 push %rbp 400b55: 48 89 e5 mov %rsp,%rbp 400b58: 48 c7 45 f8 00 00 00 movq $0x0,-0x8(%rbp) 400b5f: 00 400b60: 48 8b 45 f8 mov -0x8(%rbp),%rax 400b64: c7 00 01 00 00 00 movl $0x1,(%rax) 400b6a: 5d pop %rbp 400b6b: c3 retq
使用 addr2line 0x400b64 -e seg -afs 檢視段錯函式和對應的程式碼行數
0x0000000000400b64
segfault
seg.c:41