Hind Forsum
Hind Forsum

Reputation: 10527

On Linux, backtrace_symbols_fd function doesn't work as expected

I referred to this Stack Overflow question to test if SIGSEGV could be caught and processed:

How to automatically generate a stacktrace when my program crashes

File 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 a segmentation fault
}

I compile them:

gcc -rdynamic -g h.cpp && ./a.out

Result:

Segmentation fault (core dump)

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

Upvotes: 2

Views: 2122

Answers (2)

sorosh_sabz
sorosh_sabz

Reputation: 3003

Change the main function like below:

int main()
{
   signal(SIGSEGV, handler);  // Register handler
   int *foo = (int*)-1;  // Make a bad pointer
   printf("%d\n", *foo);  // Causes a segmentation fault
}

Upvotes: 2

Sam Varshavchik
Sam Varshavchik

Reputation: 118445

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.

Upvotes: 5

Related Questions