//------------------------------------------------------------------- // segvtrap.cpp // // This program shows how a signal-handler can be used to help // diagnose the cause of a 'Segmentation Violation' exception. // // to compile: $ g++ segvtrap.cpp -o segvtrap // to execute: $ ./segvtrap // // programmer: ALLAN CRUSE // written on: 11 MAY 2005 // revised on: 18 MAR 2009 -- for x86_64 Linux kernel 2.6.26.6 //------------------------------------------------------------------- #include // for printf() #include // for exit() #include // for sigaction() // declare the function prototype for our signal-handler void my_sigaction( int signum, siginfo_t *si, void *data ); int main( int argc, char **argv ) { // install our signal-handler static struct sigaction sa = {0}; sigemptyset( &sa.sa_mask ); sa.sa_flags = SA_SIGINFO; sa.sa_sigaction = my_sigaction; sigaction( SIGSEGV, &sa, NULL ); // setup registers with demonstration values asm(" movq $0xAAAAAAAAAAAAAAAA, %rax "); asm(" movq $0xBBBBBBBBBBBBBBBB, %rbx "); asm(" movq $0xCCCCCCCCCCCCCCCC, %rcx "); asm(" movq $0xDDDDDDDDDDDDDDDD, %rdx "); asm(" movq $0xEEEEEEEEEEEEEEEE, %rsi "); asm(" movq $0xFFFFFFFFFFFFFFFF, %rdi "); asm(" movq $0x8888888888888888, %r8 "); asm(" movq $0x9999999999999999, %r9 "); // try to execute a privileged instruction asm(" hlt "); // terminate this program with status-code 0 exit( 0 ); } void my_sigaction( int signum, siginfo_t *si, void *data ) { struct sigcontext *sc = (struct sigcontext *)((long)data+40); // display CPU registers printf( "\nsignal %d ", signum ); printf( "EFLAGS=%016lX ", sc->eflags ); printf( "\n" ); printf( "RAX=%016lX ", sc->rax ); printf( "RBX=%016lX ", sc->rbx ); printf( "RSP=%016lX ", sc->rsp ); //printf( "SS=%04lX ", sc->ss ); //printf( "ES=%04lX ", sc->es ); printf( "\n" ); printf( "RCX=%016lX ", sc->rcx ); printf( "RDX=%016lX ", sc->rdx ); printf( "RIP=%016lX ", sc->rip ); //printf( "CS=%04lX ", sc->cs ); //printf( "FS=%04lX ", sc->fs ); printf( "\n" ); printf( "RSI=%016lX ", sc->rsi ); printf( "RDI=%016lX ", sc->rdi ); printf( "RBP=%016lX ", sc->rbp ); //printf( "DS=%04lX ", sc->ds ); //printf( "GS=%04lX ", sc->gs ); printf( "\n" ); printf( " R8=%016lX ", sc->r8 ); printf( " R9=%016lX ", sc->r9 ); printf( "R10=%016lX ", sc->r10 ); printf( "\n" ); printf( "R11=%016lX ", sc->r11 ); printf( "R12=%016lX ", sc->r12 ); printf( "R13=%016lX ", sc->r13 ); printf( "\n" ); printf( "R14=%016lX ", sc->r14 ); printf( "R15=%016lX ", sc->r15 ); printf( "\n" ); // display some values from the top of the stack unsigned long *lp = (unsigned long *)sc->rsp; printf( "\n[SS:ESP] " ); for (int i = 0; i < 4; i++) printf( "%016X ", lp[i] ); // display some bytes from the instruction-stream unsigned char *ip = (unsigned char *)sc->rip; printf( "\n[CS:RIP] " ); for (int i = 0; i < 15; i++) printf( "%02X ", ip[i] ); printf( "\n\n" ); // terminate this program with status-code 1 exit( 1 ); }