概述
一般工作上,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打印堆栈的信号问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复