/* set up signal_handler as the handler for signal "sig" */ static void intercept_signal(int sig, handler_t handler) { int rc; struct sigaction act; act.sa_sigaction = (handler_3_t) handler; rc = sigfillset(&act.sa_mask); /* block all signals within handler */ ASSERT_NOERR(rc); act.sa_flags = SA_ONSTACK; /* arm the signal */ rc = sigaction(sig, &act, NULL); ASSERT_NOERR(rc); }
/* set up signal_handler as the handler for signal "sig" */ void intercept_signal(int sig, handler_3_t handler, bool sigstack) { int rc; struct sigaction act; act.sa_sigaction = (void (*)(int, siginfo_t *, void *)) handler; rc = sigfillset(&act.sa_mask); /* block all signals within handler */ ASSERT_NOERR(rc); act.sa_flags = SA_SIGINFO; if (sigstack) act.sa_flags = SA_ONSTACK; /* arm the signal */ rc = sigaction(sig, &act, NULL); ASSERT_NOERR(rc); }
/* set up signal_handler as the handler for signal "sig" */ static void intercept_signal(int sig, handler_t handler) { int rc; struct sigaction act; act.sa_sigaction = handler; #if BLOCK_IN_HANDLER rc = sigfillset(&act.sa_mask); /* block all signals within handler */ #else rc = sigemptyset(&act.sa_mask); /* no signals are blocked within handler */ #endif ASSERT_NOERR(rc); act.sa_flags = SA_SIGINFO | SA_ONSTACK; /* send 3 args to handler */ /* arm the signal */ rc = sigaction(sig, &act, NULL); ASSERT_NOERR(rc); }
/* set up signal_handler as the handler for signal "sig" */ static void intercept_signal(int sig, handler_t handler) { int rc; struct sigaction act; act.sa_sigaction = (handler_3_t) handler; /* FIXME: due to DR bug 840 we cannot block ourself in the handler * since the handler does not end in a sigreturn, so we have an empty mask * and we use SA_NOMASK */ rc = sigemptyset(&act.sa_mask); /* block no signals within handler */ ASSERT_NOERR(rc); /* FIXME: due to DR bug #654 we use SA_SIGINFO -- change it once DR works */ act.sa_flags = SA_NOMASK | SA_SIGINFO | SA_ONSTACK; /* arm the signal */ rc = sigaction(sig, &act, NULL); ASSERT_NOERR(rc); }
int main(int argc, char *argv[]) { double res = 0.; int i, j; #if defined(USE_DYNAMO) || USE_TIMER || USE_SIGSTACK int rc; #endif #if USE_SIGSTACK stack_t sigstack; #endif #if USE_TIMER struct itimerval t; #endif #ifdef USE_DYNAMO rc = dynamorio_app_init(); ASSERT_NOERR(rc); dynamorio_app_start(); #endif #if USE_TIMER intercept_signal(SIGVTALRM, (handler_t) signal_handler); t.it_interval.tv_sec = 0; t.it_interval.tv_usec = 10000; t.it_value.tv_sec = 0; t.it_value.tv_usec = 10000; rc = setitimer(ITIMER_VIRTUAL, &t, NULL); ASSERT_NOERR(rc); #endif #if USE_SIGSTACK sigstack.ss_sp = (char *) malloc(ALT_STACK_SIZE); sigstack.ss_size = ALT_STACK_SIZE; sigstack.ss_flags = SS_ONSTACK; rc = sigaltstack(&sigstack, NULL); ASSERT_NOERR(rc); # if VERBOSE fprintf(stderr, "Set up sigstack: 0x%08x - 0x%08x\n", sigstack.ss_sp, sigstack.ss_sp + sigstack.ss_size); # endif #endif intercept_signal(SIGSEGV, (handler_t) signal_handler); intercept_signal(SIGUSR1, (handler_t) signal_handler); intercept_signal(SIGUSR2, (handler_t) SIG_IGN); res = cos(0.56); fprintf(stderr, "Sending SIGUSR2\n"); kill(getpid(), SIGUSR2); fprintf(stderr, "Sending SIGUSR1\n"); kill(getpid(), SIGUSR1); #if USE_SIGSTACK /* now remove alt stack */ free(sigstack.ss_sp); sigstack.ss_sp = 0; sigstack.ss_size = 0; sigstack.ss_flags = SS_DISABLE; rc = sigaltstack(&sigstack, NULL); ASSERT_NOERR(rc); #endif fprintf(stderr, "Generating SIGSEGV\n"); #if USE_LONGJMP res = setjmp(env); if (res == 0) { *((int *)0) = 4; } #else kill(getpid(), SIGSEGV); #endif for (i=0; i<ITERS; i++) { if (i % 2 == 0) { res += cos(1./(double)(i+1)); } else { res += sin(1./(double)(i+1)); } j = (i << 4) / (i | 0x38); a[i] += j; } fprintf(stderr, "%f\n", res); #if USE_TIMER memset(&t, 0, sizeof(t)); rc = setitimer(ITIMER_VIRTUAL, &t, NULL); ASSERT_NOERR(rc); if (timer_hits == 0) fprintf(stderr, "Got 0 timer hits!\n"); else fprintf(stderr, "Got some timer hits!\n"); #endif #ifdef USE_DYNAMO dynamorio_app_stop(); dynamorio_app_exit(); #endif return 0; }
static void signal_handler(int sig, siginfo_t *siginfo, ucontext_t *ucxt) { #if VERBOSE fprintf(stderr, "signal_handler: sig=%d, retaddr=0x%08x, fpregs=0x%08x\n", sig, *(&sig - 1), ucxt->uc_mcontext.fpregs); #else # if USE_TIMER if (sig != SIGVTALRM) # endif fprintf(stderr, "signal_handler: sig=%d\n", sig); #endif switch (sig) { case SIGSEGV: { #if VERBOSE struct sigcontext *sc = (struct sigcontext *) &(ucxt->uc_mcontext); void *pc = (void *) sc->SC_XIP; #endif #if USE_LONGJMP && BLOCK_IN_HANDLER sigset_t set; int rc; #endif #if VERBOSE fprintf(stderr, "Got SIGSEGV @ 0x%08x\n", pc); #else fprintf(stderr, "Got SIGSEGV\n"); #endif #if USE_LONGJMP # if BLOCK_IN_HANDLER /* longjmp will bypass sigreturn, and sigreturn is what resets * the set of blocked signals, so we have to unblock them here */ rc = sigemptyset(&set); /* reset blocked signals */ ASSERT_NOERR(rc); sigprocmask(SIG_SETMASK, &set, NULL); # endif longjmp(env, 1); #endif break; } case SIGUSR1: { #if VERBOSE struct sigcontext *sc = (struct sigcontext *) &(ucxt->uc_mcontext); void *pc = (void *) sc->SC_XIP; fprintf(stderr, "Got SIGUSR1 @ 0x%08x\n", pc); #else fprintf(stderr, "Got SIGUSR1\n"); #endif break; } #if USE_TIMER case SIGVTALRM: { struct sigcontext *sc = (struct sigcontext *) &(ucxt->uc_mcontext); void *pc = (void *) sc->SC_XIP; #if VERBOSE fprintf(stderr, "Got SIGVTALRM @ 0x%08x\n", pc); #endif timer_hits++; break; } #endif default: assert(0); } }