#include <stdio.h>
#include <stdlib.h>
#include <execinfo.h>
#include <signal.h>
#include <unistd.h>

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

	// get void*'s for all entries on the stack
	size = backtrace ( array, 10 );

	// print out all the frames to stderr
	fprintf ( stderr, "Error: signal %d\n", sig );

	char **buffer = backtrace_symbols ( array, size );

	if ( buffer == 0 ) {
		fprintf ( stderr, "backtrace_symbols" );
		exit ( 1 );
	}

	fprintf ( stderr, "Obtained %zd stack frames.\n", size );
	for ( size_t i = 0; i < size; i++ ) {
		//fprintf ( stderr, "%lu. %s - %p\n", i, buffer [ i ], array [ i ] );
		fprintf ( stderr, "%d. %s - %p\n", i, buffer [ i ], array [ i ] );
	}
	fprintf ( stderr, "\n\n" );

	free ( buffer );
	exit ( 1 );
}

void baz ( ) {
	int *foo = ( int * ) -1;      // Make a bad pointer
	printf ( "%d\n", *foo );  // causes segfault
}

void bar ( ) {
	baz ( );
}

void foo ( ) {
	bar ( );
}

int main ( int argc, char ** argv ) {
	signal ( SIGSEGV, handler );
	foo ( );
	return 0;
}
