Get rid of ASM_GLOBAL_DIRECTIVE.
[platform/upstream/glibc.git] / debug / tst-longjmp_chk2.c
1 /* Test case mostly written by Paolo Bonzini <pbonzini@redhat.com>.  */
2 #include <assert.h>
3 #include <setjmp.h>
4 #include <signal.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <sys/types.h>
8 #include <sys/time.h>
9 #include <sys/resource.h>
10
11
12 static jmp_buf mainloop;
13 static sigset_t mainsigset;
14 static int pass;
15
16
17 static void
18 stackoverflow_handler (int sig)
19 {
20   stack_t altstack;
21   pass++;
22   sigaltstack (NULL, &altstack);
23   /* Using printf is not really kosher in signal handlers but we know
24      it will work.  */
25   printf ("%*sin signal handler\n", pass, "");
26   if (altstack.ss_flags & SS_ONSTACK)
27     printf ("%*son alternate stack\n", pass, "");
28   siglongjmp (mainloop, pass);
29 }
30
31
32 static volatile int *
33 recurse_1 (int n, volatile int *p)
34 {
35   if (n >= 0)
36     *recurse_1 (n + 1, p) += n;
37   return p;
38 }
39
40
41 static int
42 recurse (int n)
43 {
44   int sum = 0;
45   return *recurse_1 (n, &sum);
46 }
47
48
49 static int
50 do_test (void)
51 {
52   char mystack[SIGSTKSZ];
53   stack_t altstack;
54   struct sigaction action;
55   sigset_t emptyset;
56   /* Before starting the endless recursion, try to be friendly to the user's
57      machine.  On some Linux 2.2.x systems, there is no stack limit for user
58      processes at all.  We don't want to kill such systems.  */
59   struct rlimit rl;
60   rl.rlim_cur = rl.rlim_max = 0x100000; /* 1 MB */
61   setrlimit (RLIMIT_STACK, &rl);
62   /* Install the alternate stack.  */
63   altstack.ss_sp = mystack;
64   altstack.ss_size = sizeof (mystack);
65   altstack.ss_flags = 0; /* no SS_DISABLE */
66   if (sigaltstack (&altstack, NULL) < 0)
67     {
68       puts ("first sigaltstack failed");
69       return 0;
70     }
71   /* Install the SIGSEGV handler.  */
72   sigemptyset (&action.sa_mask);
73   action.sa_handler = &stackoverflow_handler;
74   action.sa_flags = SA_ONSTACK;
75   sigaction (SIGSEGV, &action, (struct sigaction *) NULL);
76   sigaction (SIGBUS, &action, (struct sigaction *) NULL);
77
78   /* Save the current signal mask.  */
79   sigemptyset (&emptyset);
80   sigprocmask (SIG_BLOCK, &emptyset, &mainsigset);
81
82   /* Provoke two stack overflows in a row.  */
83   if (sigsetjmp (mainloop, 1) != 0)
84     {
85       assert (pass != 0);
86       printf ("%*sout of signal handler\n", pass, "");
87     }
88   else
89     assert (pass == 0);
90
91   sigaltstack (NULL, &altstack);
92   if (altstack.ss_flags & SS_ONSTACK)
93     printf ("%*son alternate stack\n", pass, "");
94   else
95     printf ("%*snot on alternate stack\n", pass, "");
96
97   if (pass < 2)
98     {
99       recurse (0);
100       puts ("recurse call returned");
101       return 2;
102     }
103
104   altstack.ss_flags |= SS_DISABLE;
105   if (sigaltstack (&altstack, NULL) == -1)
106     printf ("disabling alternate stack failed\n");
107   else
108     printf ("disabling alternate stack succeeded \n");
109
110   return 0;
111 }
112
113 #define TEST_FUNCTION do_test ()
114 #include "../test-skeleton.c"