/* Test of correct simulation for active stack. */ #include <assert.h> #include <signal.h> #include <stdio.h> #include <ucontext.h> static char altstack_map[8096]; static volatile stack_t *sp; static void sighandler(int sig) { /* Check that the alternate stack is active. */ assert(sp->ss_sp == altstack_map); assert(sp->ss_size == sizeof(altstack_map)); assert(sp->ss_flags == SS_ONSTACK); } int main(void) { stack_t mainstack; stack_t altstack; struct sigaction sa; /* Obtain an address inside the stack using a dirty trick. */ void *local = &sa; /* Get an address for stack definition. */ if (getustack((stack_t**)&sp)) { perror("getustack"); return 1; } /* Check the current stack. */ assert(sp->ss_sp <= local); assert(local < (void*)((char*)sp->ss_sp + sp->ss_size)); assert(sp->ss_flags == 0); /* Backup the current stack. */ mainstack = *sp; /* Setup a signal handler. */ sa.sa_handler = sighandler; sa.sa_flags = SA_ONSTACK; if (sigfillset(&sa.sa_mask)) { perror("sigfillset"); return 1; } if (sigaction(SIGUSR1, &sa, NULL)) { perror("sigaction"); return 1; } /* Setup an alternate stack. */ altstack.ss_sp = altstack_map; altstack.ss_size = sizeof(altstack_map); altstack.ss_flags = 0; if (sigaltstack(&altstack, NULL)) { perror("sigaltstack"); return 1; } /* Raise a signal. */ raise(SIGUSR1); /* Check the current stack. */ assert(mainstack.ss_sp == sp->ss_sp); assert(mainstack.ss_size == sp->ss_size); assert(mainstack.ss_flags == sp->ss_flags); return 0; }