Hind Forsum Hind Forsum - 2 months ago 18
Linux Question

On linux, backtrace_symbols_fd function doesn't work as expected

I referred to this web thread to test if SIGSEGV could be caught and processed:

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
}


I compile them:

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


Well it doesn't print out the call stack as I expected. Do I have to setup any system parameters?

Answer

There are two problems.

  1. A SIGSEGV handler is not registered using sigaction().

  2. Within the signal handler, fprintf is called. fprintf is not a reentrant library function, and it cannot be called from a signal handler. Especially for a SIGSEGV when, potentially, the entire heap has been nuked from high orbit, and stderrs, internal file buffer could be a smoking crater. Only system calls, like write() can be safely called from a signal handler.

Comments