/* $Id: fault.c,v 1.5 2008/10/28 17:39:16 kostik Exp $ */ #include #include #include #include #include #include #include #include extern char *fault_instr; int run; void sigsegv_sigaction(int signo, siginfo_t *si, void *c) { ucontext_t *uc; mcontext_t *mc; uc = c; mc = &uc->uc_mcontext; printf("SIGSEGV run %d err %x ds %x ss %x es %x fs %x gs %x\n", run, mc->mc_err, mc->mc_ds, mc->mc_ss, mc->mc_es, mc->mc_fs, mc->mc_gs); switch (run) { case 0: mc->mc_ds = 0x1111; break; case 1: mc->mc_es = 0x1111; break; case 2: mc->mc_fs = 0x1111; break; case 3: mc->mc_gs = 0x1111; break; case 4: mc->mc_ss = 0x1111; break; case 5: _exit(11); } run++; } void fault(void) { __asm__ volatile(".globl\tfault_instr;fault_instr:\ttestl\t$0,0\n"); } int main(int argc, char *argv[]) { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_sigaction = sigsegv_sigaction; sa.sa_flags = SA_SIGINFO; if (sigaction(SIGSEGV, &sa, NULL) == -1) { fprintf(stderr, "sigaction: %s\n", strerror(errno)); return (1); } if (sigaction(SIGBUS, &sa, NULL) == -1) { fprintf(stderr, "sigaction: %s\n", strerror(errno)); return (1); } fault(); return (0); }