打印调用栈可以在程序出现死机的时候(如出现 SIGABRT、SIGSEGV等一些信号错误)是很有用的信息,有可能就不需要 core file 来协助排查问题了。通过 man backtrace 可以得到一个例子的源码:
cpp
#define SIZE 100
static void backTracePro(void)
{
int j, nptrs;
void *buffer[SIZE];
char **strings;
nptrs = backtrace(buffer, SIZE);
printf("****************************************\n");//这行我自己加的
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);
}
然后可以把这个函数放在信号回调函数里,所以先需要设置一下信号处理函数,函数:int sigaction (int __sig, const struct sigaction *__restrict __act, struct sigaction *__restrict __oact),
cpp
static bool initSignalCallBack()
{
struct sigaction sigact;
memset(&sigact, 0, sizeof(sigact));
sigact.sa_handler = signalHandler;
sigemptyset(&(sigact.sa_mask));
int ret = sigaction(SIGABRT, &sigact, NULL);
if(0 == ret)
{
ret |= sigaction(SIGSEGV, &sigact, NULL);
}
else
{
strerror(errno);
return false;
}
if(ret)
{
strerror(errno);
}
return ret == 0;
}
所以可以把 backTracePro() 放到信号回调函数 signalHandler() 里,看看执行结果:
接下来用 c++filt 解析一下符号就可以看到调用到哪个函数了。