在linux上,backtrace_symbols_fd函数不能按预期工作

时间:2016-09-30 10:33:10

标签: c++ linux dynamic trace sigsegv

我提到这个网络线程来测试是否可以捕获和处理SIGSEGV:

How to generate a stacktrace when my gcc C++ app crashes

$ cat h.cpp
#include <stdio.h>
#include <execinfo.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>

void handler(int sig) {
  void *array[10];
  size_t size = backtrace(array, 10);

  // print out all the frames to stderr
  fprintf(stderr, "Error: signal %d:\n", sig);
  backtrace_symbols_fd(array, size, STDERR_FILENO);
  exit(1);
}
int main()
{
  int *foo = (int*)-1; // make a bad pointer
  printf("%d\n", *foo);       // causes segfault
}

我编译它们:

$ gcc -rdynamic -g h.cpp && ./a.out
$ Segmentation fault(core dump)

好吧它没有像我预期的那样打印掉调用堆栈。我是否必须设置任何系统参数?

2 个答案:

答案 0 :(得分:1)

更改主要功能如下

int main()
{
   signal(SIGSEGV, handler);  // register handler
   int *foo = (int*)-1;  // make a bad pointer
   printf("%d\n", *foo);  // causes segfault
}

答案 1 :(得分:1)

有两个问题。

  1. SIGSEGV处理程序未使用sigaction()注册。

  2. 在信号处理程序中,调用fprintffprintf不是可重入的库函数,无法从信号处理程序中调用它。特别是对于SIGSEGV,当潜在地,整个堆已经从高轨道和stderr进行核心时,内部文件缓冲区可能是一个吸烟陨石坑。只能从信号处理程序中安全地调用write()等系统调用。