我是靠谱客的博主 欢呼吐司,最近开发中收集的这篇文章主要介绍backtrace打印堆栈的信号问题,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一般工作上,linux通常会使用gdb跟踪堆栈,但是某些情况下(比如core文件较大,core文件不完整),需要采用backtrace来打印堆栈到日志文件中。

      如何使用backtrace:

1 #include <execinfo.h>

2 man backtrace,backtrace_symbols 2个接口

3 设置信号捕捉函数

#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>


void print_trace (void){
	void *array[10];
	size_t size;
	char **strings;
    size_t i;

	size = backtrace (array, 10);
	strings = backtrace_symbols (array, size);
	if (NULL == strings)
	{
		perror("backtrace_synbols");
		exit(0);
	}

	printf ("Obtained %zd stack frames.n", size);

	for (i = 0; i < size; i++)
		printf ("%sn", strings[i]);

	free (strings);
 	strings = NULL;
}

void dummy_function (void){
	print_trace ();
}

void signal_handle(int signo){
	printf("%s signo:%dn", __FUNCTION__, signo);
	dummy_function ();
	sleep(1);
}

void build_signal(){
	struct sigaction act, oact;
	act.sa_handler = signal_handle;
	sigemptyset(&act.sa_mask);
	act.sa_flags = SA_SIGINFO | SA_RESETHAND;
	sigaction(SIGINT, &act, &oact);
	sigaction(SIGSEGV, &act, &oact);
}

int main (int argc, char** argv){
	build_signal();
	
	while(1){
		sleep(3);
	}	
	return 0;
}
由于SIGINT和SIGSEGV信号被捕捉,按下ctrl+c 会进入信号处理函数,但是SA_RESETHAND的参数设置,第二次会默认处理该信号。

正常逻辑需要不但进入信号处理函数打印堆栈,还需要rethrow该信号,暂时没有找到rethrow的方式,只能在信号处理函数中kill一把了,

void signal_handle(int signo){
printf("%s signo:%dn", __FUNCTION__, signo);
dummy_function ();
sleep(1);
kill(getpid(), signo)
}

最后

以上就是欢呼吐司为你收集整理的backtrace打印堆栈的信号问题的全部内容,希望文章能够帮你解决backtrace打印堆栈的信号问题所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部