Linux中backtrace()系列函数的应用实例

一、引言
backtrace()系列函数可用来输出代码出错时的函数调用关系。

A backtrace is the series of currently active function calls for the program. 

#include <execinfo.h>
int backtrace(void **buffer, int size);
char **backtrace_symbols(void *const *buffer, int size);
void backtrace_symbols_fd(void *const *buffer, int size, int fd);

二、示例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <strings.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <execinfo.h> 

#define SIZE	(100)
static sigset_t signals_handled;
	
static void dbg_backtrace(void)
{
	int i, nline;
	void *buffer[SIZE];
	char **strings;
	
	nline = backtrace(buffer, SIZE);
	printf("addr: %d = backtrace()\n", nline);
	
	strings = backtrace_symbols(buffer, nline);
	if (NULL == strings) {
		perror("backtrace_symbols()\n");
		exit(EXIT_FAILURE);
	}
	
	for (i = 0; i < nline; i ++) {
		printf("callback: %s\n", strings[j]);
	}
	/* backtrace_symbols() 内部有调用malloc函数 */
	free(strings);
}

static void sig_handler_hup(int sig)
{
	printf("%s() %d\n\n", __func__, sig);
}

static void sig_handler_debug(int sig)
{
	printf("%s() %d\n\n", __func__, sig);
}

static void sig_handler_usr2(int sig)
{
	printf("%s() %d\n\n", __func__, sig);
}

static void sig_handler_fatal(int sig)
{
	printf("Fatal signal %d\n\n", sig);
	
	dbg_backtrace();
	exit(127);
}

void signals_setup(void)
{
	struct sigaction sa;
	
	sigemptyset(&signals_handled);
	sigaddset(&signals_handled, SIGHUP);
	sigaddset(&signals_handled, SIGINT);
	sigaddset(&signals_handled, SIGTERM);
	sigaddset(&signals_handled, SIGUSR2);
	
#define SIGNAL(s, handler)	do { \
	sa.sa_handler = handler;	\
	if (sigaction(s, &sa, NULL) < 0) \
		printf("could not set signal handler (%d): %m", s); \
	} while(0);
	
	sa.sa_mask = signals_handled;
	sa.sa_flags = 0;
	
	SIGNAL(SIGHUP, sig_handler_hup);
	SIGNAL(SIGUSR1, sig_handler_debug);
	SIGNAL(SIGUSR2, sig_handler_usr2);
	SIGNAL(SIGABRT, sig_handler_fatal);
	SIGNAL(SIGALRM, sig_handler_fatal);
	SIGNAL(SIGFPE, sig_handler_fatal);
	SIGNAL(SIGILL, sig_handler_fatal);
	SIGNAL(SIGPIPE, sig_handler_fatal);
	SIGNAL(SIGQUIT, sig_handler_fatal);
	SIGNAL(SIGSEGV, sig_handler_fatal);
	
	signal(SIGPIPE, SIG_IGN);
}

void mem_err(void)
{
	char *prt = NULL;
	printf("%s()\n", __func__);
	
	*prt = '1';
}

int main(int argc, char **argv)
{
	signals_setup();
	int i = 0;
	
	for (; ;) {
		i ++;
		if (i > 10) {
			mem_err();
		}
		
		// printf("i: %d\n", i);
		sleep(2);
	}
		
	return 0;
}

运行结果:
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值