145
|
1 /* { dg-do run { target hppa*-*-hpux* *-*-linux* *-*-gnu* powerpc*-*-darwin* *-*-darwin[912]* *-*-uclinux* } } */
|
111
|
2 /* { dg-options "-fexceptions -fnon-call-exceptions -O2" } */
|
|
3 /* Verify that cleanups work with exception handling through signal frames
|
|
4 on alternate stack. */
|
|
5
|
|
6 #include <unwind.h>
|
|
7 #include <stdlib.h>
|
|
8 #include <signal.h>
|
|
9 #include <unistd.h>
|
|
10 #include <string.h>
|
|
11
|
|
12 static _Unwind_Reason_Code
|
|
13 force_unwind_stop (int version, _Unwind_Action actions,
|
|
14 _Unwind_Exception_Class exc_class,
|
|
15 struct _Unwind_Exception *exc_obj,
|
|
16 struct _Unwind_Context *context,
|
|
17 void *stop_parameter)
|
|
18 {
|
|
19 if (actions & _UA_END_OF_STACK)
|
|
20 abort ();
|
|
21 return _URC_NO_REASON;
|
|
22 }
|
|
23
|
|
24 static void force_unwind ()
|
|
25 {
|
|
26 struct _Unwind_Exception *exc
|
|
27 = (struct _Unwind_Exception *) malloc (sizeof (*exc));
|
|
28 memset (&exc->exception_class, 0, sizeof (exc->exception_class));
|
|
29 exc->exception_cleanup = 0;
|
|
30
|
|
31 #ifndef __USING_SJLJ_EXCEPTIONS__
|
|
32 _Unwind_ForcedUnwind (exc, force_unwind_stop, 0);
|
|
33 #else
|
|
34 _Unwind_SjLj_ForcedUnwind (exc, force_unwind_stop, 0);
|
|
35 #endif
|
|
36
|
|
37 abort ();
|
|
38 }
|
|
39
|
|
40 int count;
|
|
41 char *null;
|
|
42
|
|
43 static void counter (void *p __attribute__((unused)))
|
|
44 {
|
|
45 ++count;
|
|
46 }
|
|
47
|
|
48 static void handler (void *p __attribute__((unused)))
|
|
49 {
|
|
50 if (count != 2)
|
|
51 abort ();
|
|
52 exit (0);
|
|
53 }
|
|
54
|
|
55 static int __attribute__((noinline)) fn5 ()
|
|
56 {
|
|
57 char dummy __attribute__((cleanup (counter)));
|
|
58 force_unwind ();
|
|
59 return 0;
|
|
60 }
|
|
61
|
|
62 static void fn4 (int sig, siginfo_t *info, void *ctx)
|
|
63 {
|
|
64 char dummy __attribute__((cleanup (counter)));
|
|
65 fn5 ();
|
|
66 null = NULL;
|
|
67 }
|
|
68
|
|
69 static void fn3 ()
|
|
70 {
|
|
71 abort ();
|
|
72 }
|
|
73
|
|
74 static int __attribute__((noinline)) fn2 ()
|
|
75 {
|
|
76 *null = 0;
|
|
77 fn3 ();
|
|
78 return 0;
|
|
79 }
|
|
80
|
|
81 static int __attribute__((noinline)) fn1 ()
|
|
82 {
|
|
83 stack_t ss;
|
|
84 struct sigaction s;
|
|
85
|
|
86 ss.ss_size = 4 * sysconf (_SC_PAGESIZE);
|
|
87 if (ss.ss_size < SIGSTKSZ)
|
|
88 ss.ss_size = SIGSTKSZ;
|
|
89 ss.ss_sp = malloc (ss.ss_size);
|
|
90 if (ss.ss_sp == NULL)
|
|
91 exit (1);
|
|
92 ss.ss_flags = 0;
|
|
93 if (sigaltstack (&ss, NULL) < 0)
|
|
94 exit (1);
|
|
95
|
|
96 sigemptyset (&s.sa_mask);
|
|
97 s.sa_sigaction = fn4;
|
|
98 s.sa_flags = SA_RESETHAND | SA_ONSTACK;
|
|
99 sigaction (SIGSEGV, &s, NULL);
|
|
100 sigaction (SIGBUS, &s, NULL);
|
|
101 fn2 ();
|
|
102 return 0;
|
|
103 }
|
|
104
|
|
105 static int __attribute__((noinline)) fn0 ()
|
|
106 {
|
|
107 char dummy __attribute__((cleanup (handler)));
|
|
108 fn1 ();
|
|
109 null = 0;
|
|
110 return 0;
|
|
111 }
|
|
112
|
|
113 int main()
|
|
114 {
|
|
115 fn0 ();
|
|
116 abort ();
|
|
117 }
|