Reputation: 10527
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
#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
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
Reputation: 118445
There are two problems.
A SIGSEGV
handler is not registered using sigaction()
.
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 stderr
s, internal file buffer could be a smoking crater. Only system calls, like write()
can be safely called from a signal handler.
Upvotes: 5