| /* 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; |
| } |
| |