1
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <signal.h>
6#include "tests/sys_mman.h"
7
8void sig_handler(int sig){
9  int var;
10  fprintf(stderr, "caught signal, local var is on %p\n", &var);
11}
12
13int main(int argv, char** argc) {
14  int res, i;
15  stack_t sigstk;
16  struct sigaction act;
17  static const int size = SIGSTKSZ*2;
18  // We give EXEC permissions because this won't work on ppc32 unless you
19  // ask for an alt stack with EXEC permissions,
20  // since signal returning requires execution of code on the stack.
21  char *stk = (char *)mmap(0, size, PROT_READ|PROT_WRITE|PROT_EXEC,
22                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
23  sigstk.ss_sp = stk;
24
25  sigstk.ss_size = size;
26  sigstk.ss_flags = 0;
27  fprintf(stderr, "calling sigaltstack, stack base is %p\n", sigstk.ss_sp);
28  if (sigaltstack(&sigstk,0)<0) perror("sigaltstack");
29
30  fprintf(stderr,"setting sigaction\n");
31  act.sa_flags=SA_ONSTACK;
32  act.sa_handler=&sig_handler;
33  sigemptyset(&act.sa_mask);
34  res = sigaction(SIGUSR1,&act,0);
35  fprintf(stderr, "res = %d\n", res);
36  fprintf(stderr, "raising the signal\n");
37  raise(SIGUSR1);
38
39  /* Loop long enough so valgrind has a forced context switch and
40     actually delivers the signal before the thread exits. */
41  for (i = 0; i < 1000000; i++) ;
42
43  fprintf(stderr, "done\n");
44  return 0;
45}
46