/* Orion Lawlor's Short UNIX Examples, olawlor@acm.org 2004/2/16

Shows how to use POSIX siginfo_t to find the faulting
address from a signal handler.
*/
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#ifdef SOLARIS /* needed with at least Solaris 8 */
#include <siginfo.h>
#endif

void handler(int cause, siginfo_t *HowCome, void *ucontextv) {
        printf( "SIGSEGV raised at address %p.  Good.\n", HowCome->si_addr);
	exit(1);
}

int main(){ 
	int *where=(int *)0x123;
	
/* Install our signal handler */
        struct sigaction sa;

        sa.sa_sigaction = handler;
        sigemptyset( &sa.sa_mask );
        sa.sa_flags = 0;
	sa.sa_flags |= SA_SIGINFO; /* we want a siginfo_t */
	sa.sa_flags |= SA_RESTART; /* restart interrupted syscalls (no EINTR errors) */
        if (sigaction (SIGSEGV, &sa, 0)) {
		perror("sigaction");
		exit(1);
        }

/* Do something that generates a segfault */
        printf( "About to write to %p\n", where);
        *where = 'a';

        return(0);
}

/*<@>
<@> ******** Program output: ********
<@> About to write to 0x123
<@> SIGSEGV raised at address 0x123.  Good.
<@> */
