1. 程式人生 > >使用backtrace和backtrace_symbols追蹤段錯

使用backtrace和backtrace_symbols追蹤段錯

結合文章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