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