This source file includes following definitions.
- stackoverflow_handler_continuation
 
- stackoverflow_handler
 
- recurse_1
 
- recurse
 
- main
 
- main
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 #include <config.h>
  20 
  21 
  22 #include "sigsegv.h"
  23 
  24 #include <stdio.h>
  25 #include <limits.h>
  26 
  27 #if HAVE_STACK_OVERFLOW_RECOVERY
  28 
  29 # if defined _WIN32 && !defined __CYGWIN__
  30   
  31   typedef int sigset_t;
  32 #  define sigemptyset(set)
  33 #  define sigprocmask(how,set,oldset)
  34 # endif
  35 
  36 # include <stddef.h> 
  37 # include <stdlib.h> 
  38 # include <signal.h>
  39 # include <setjmp.h>
  40 # if HAVE_SETRLIMIT
  41 #  include <sys/types.h>
  42 #  include <sys/time.h>
  43 #  include <sys/resource.h>
  44 # endif
  45 # include "altstack-util.h"
  46 
  47 static jmp_buf mainloop;
  48 static sigset_t mainsigset;
  49 
  50 static volatile int pass = 0;
  51 
  52 static volatile char *stack_lower_bound;
  53 static volatile char *stack_upper_bound;
  54 
  55 static void
  56 stackoverflow_handler_continuation (void *arg1, void *arg2, void *arg3)
     
  57 {
  58   int arg = (int) (long) arg1;
  59   longjmp (mainloop, arg);
  60 }
  61 
  62 static void
  63 stackoverflow_handler (int emergency, stackoverflow_context_t scp)
     
  64 {
  65   char dummy;
  66   volatile char *addr = &dummy;
  67   if (!(addr >= stack_lower_bound && addr <= stack_upper_bound))
  68     abort ();
  69   pass++;
  70   printf ("Stack overflow %d caught.\n", pass);
  71   sigprocmask (SIG_SETMASK, &mainsigset, NULL);
  72   sigsegv_leave_handler (stackoverflow_handler_continuation,
  73                          (void *) (long) (emergency ? -1 : pass), NULL, NULL);
  74 }
  75 
  76 static volatile int *
  77 recurse_1 (int n, volatile int *p)
     
  78 {
  79   if (n < INT_MAX)
  80     *recurse_1 (n + 1, p) += n;
  81   return p;
  82 }
  83 
  84 static int
  85 recurse (volatile int n)
     
  86 {
  87   return *recurse_1 (n, &n);
  88 }
  89 
  90 int
  91 main ()
     
  92 {
  93   sigset_t emptyset;
  94 
  95 # if HAVE_SETRLIMIT && defined RLIMIT_STACK
  96   
  97 
  98 
  99   struct rlimit rl;
 100   rl.rlim_cur = rl.rlim_max = 0x100000; 
 101   setrlimit (RLIMIT_STACK, &rl);
 102 # endif
 103 
 104   
 105   prepare_alternate_stack ();
 106 
 107   
 108   if (stackoverflow_install_handler (&stackoverflow_handler,
 109                                      mystack, MYSTACK_SIZE)
 110       < 0)
 111     exit (2);
 112   stack_lower_bound = mystack;
 113   stack_upper_bound = mystack + MYSTACK_SIZE - 1;
 114 
 115   
 116   sigemptyset (&emptyset);
 117   sigprocmask (SIG_BLOCK, &emptyset, &mainsigset);
 118 
 119   
 120   switch (setjmp (mainloop))
 121     {
 122     case -1:
 123       printf ("emergency exit\n"); exit (1);
 124     case 0: case 1:
 125       printf ("Starting recursion pass %d.\n", pass + 1);
 126       recurse (0);
 127       printf ("no endless recursion?!\n"); exit (1);
 128     case 2:
 129       break;
 130     default:
 131       abort ();
 132     }
 133 
 134   
 135   check_alternate_stack_no_overflow ();
 136 
 137   printf ("Test passed.\n");
 138   exit (0);
 139 }
 140 
 141 #else
 142 
 143 int
 144 main ()
     
 145 {
 146   return 77;
 147 }
 148 
 149 #endif