1 /* Stack overflow handling.
3 Copyright (C) 2002, 2004, 2006, 2008 Free Software Foundation, Inc.
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 /* Written by Paul Eggert. */
22 A program that uses alloca, dynamic arrays, or large local
23 variables may extend the stack by more than a page at a time. If
24 so, when the stack overflows the operating system may not detect
25 the overflow until the program uses the array, and this module may
26 incorrectly report a program error instead of a stack overflow.
28 To avoid this problem, allocate only small objects on the stack; a
29 program should be OK if it limits single allocations to a page or
30 less. Allocate larger arrays in static storage, or on the heap
31 (e.g., with malloc). Yes, this is a pain, but we don't know of any
32 better solution that is portable.
34 No attempt has been made to deal with multithreaded applications. */
40 # define __attribute__(x)
45 #define _(msgid) gettext (msgid)
49 # define ENOTSUP EINVAL
53 #if ! HAVE_STACK_T && ! defined stack_t
54 typedef struct sigaltstack stack_t;
57 # define SIGSTKSZ 16384
63 /* Posix 2001 declares ucontext_t in <ucontext.h>, Posix 200x in
66 # include <ucontext.h>
71 # define STDERR_FILENO 2
81 #if defined SA_ONSTACK && defined SA_SIGINFO
82 # define SIGACTION_WORKS 1
84 # define SIGACTION_WORKS 0
87 extern char *program_name;
89 /* The user-specified action to take when a SEGV-related program error
90 or stack overflow occurs. */
91 static void (* volatile segv_action) (int);
93 /* Translated messages for program errors and stack overflow. Do not
94 translate them in the signal handler, since gettext is not
96 static char const * volatile program_error_message;
97 static char const * volatile stack_overflow_message;
99 /* Output an error message, then exit with status EXIT_FAILURE if it
100 appears to have been a stack overflow, or with a core dump
101 otherwise. This function is async-signal-safe. */
103 static void die (int) __attribute__ ((noreturn));
109 message = signo ? program_error_message : stack_overflow_message;
110 write (STDERR_FILENO, program_name, strlen (program_name));
111 write (STDERR_FILENO, ": ", 2);
112 write (STDERR_FILENO, message, strlen (message));
113 write (STDERR_FILENO, "\n", 1);
115 _exit (exit_failure);
120 #if (HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK) || HAVE_LIBSIGSEGV
122 /* Storage for the alternate signal stack. */
125 char buffer[SIGSTKSZ];
127 /* These other members are for proper alignment. There's no
128 standard way to guarantee stack alignment, but this seems enough
133 } alternate_signal_stack;
136 null_action (int signo __attribute__ ((unused)))
140 #endif /* SIGALTSTACK || LIBSIGSEGV */
142 /* Only use libsigsegv if we need it; platforms like Solaris can
143 detect stack overflow without the overhead of an external
145 #if HAVE_LIBSIGSEGV && ! HAVE_XSI_STACK_OVERFLOW_HEURISTIC
147 /* Nonzero if general segv handler could not be installed. */
148 static volatile int segv_handler_missing;
150 /* Handle a segmentation violation and exit if it cannot be stack
151 overflow. This function is async-signal-safe. */
153 static int segv_handler (void *address __attribute__ ((unused)),
159 sprintf (buf, "segv_handler serious=%d\n", serious);
160 write (STDERR_FILENO, buf, strlen (buf));
164 /* If this fault is not serious, return 0 to let the stack overflow
165 handler take a shot at it. */
171 /* Handle a segmentation violation that is likely to be a stack
172 overflow and exit. This function is async-signal-safe. */
174 static void overflow_handler (int, stackoverflow_context_t)
175 __attribute__ ((noreturn));
177 overflow_handler (int emergency,
178 stackoverflow_context_t context __attribute__ ((unused)))
183 sprintf (buf, "overflow_handler emergency=%d segv_handler_missing=%d\n",
184 emergency, segv_handler_missing);
185 write (STDERR_FILENO, buf, strlen (buf));
189 die ((!emergency || segv_handler_missing) ? 0 : SIGSEGV);
192 /* Set up ACTION so that it is invoked on C stack overflow. Return -1
193 (setting errno) if this cannot be done.
195 When ACTION is called, it is passed an argument equal to SIGSEGV
196 for a segmentation violation that does not appear related to stack
197 overflow, and is passed zero otherwise. On many platforms it is
198 hard to tell; when in doubt, zero is passed.
200 A null ACTION acts like an action that does nothing.
202 ACTION must be async-signal-safe. ACTION together with its callees
203 must not require more than SIGSTKSZ bytes of stack space. Also,
204 ACTION should not call longjmp, because this implementation does
205 not guarantee that it is safe to return to the original stack. */
208 c_stack_action (void (*action) (int))
210 segv_action = action ? action : null_action;
211 program_error_message = _("program error");
212 stack_overflow_message = _("stack overflow");
214 /* Always install the overflow handler. */
215 if (stackoverflow_install_handler (overflow_handler,
216 alternate_signal_stack.buffer,
217 sizeof alternate_signal_stack.buffer))
222 /* Try installing a general handler; if it fails, then treat all
223 segv as stack overflow. */
224 segv_handler_missing = sigsegv_install_handler (segv_handler);
228 #elif HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK
230 /* Direction of the C runtime stack. This function is
231 async-signal-safe. */
234 # define find_stack_direction(ptr) STACK_DIRECTION
237 find_stack_direction (char const *addr)
240 return ! addr ? find_stack_direction (&dummy) : addr < &dummy ? 1 : -1;
246 /* Handle a segmentation violation and exit. This function is
247 async-signal-safe. */
249 static void segv_handler (int, siginfo_t *, void *) __attribute__((noreturn));
251 segv_handler (int signo, siginfo_t *info,
252 void *context __attribute__ ((unused)))
254 /* Clear SIGNO if it seems to have been a stack overflow. */
255 if (0 < info->si_code)
257 # if ! HAVE_XSI_STACK_OVERFLOW_HEURISTIC
258 /* We can't easily determine whether it is a stack overflow; so
259 assume that the rest of our program is perfect (!) and that
260 this segmentation violation is a stack overflow.
262 Note that although both Linux and Solaris provide
263 sigaltstack, SA_ONSTACK, and SA_SIGINFO, currently only
264 Solaris satisfies the XSI heueristic. This is because
265 Solaris populates uc_stack with the details of the
266 interrupted stack, while Linux populates it with the details
267 of the current stack. */
270 /* If the faulting address is within the stack, or within one
271 page of the stack end, assume that it is a stack
273 ucontext_t const *user_context = context;
274 char const *stack_base = user_context->uc_stack.ss_sp;
275 size_t stack_size = user_context->uc_stack.ss_size;
276 char const *faulting_address = info->si_addr;
277 size_t s = faulting_address - stack_base;
278 size_t page_size = sysconf (_SC_PAGESIZE);
279 if (find_stack_direction (NULL) < 0)
281 if (s < stack_size + page_size)
288 "segv_handler fault=%p base=%p size=%lx page=%lx signo=%d\n",
289 faulting_address, stack_base, (unsigned long) stack_size,
290 (unsigned long) page_size, signo);
291 write (STDERR_FILENO, buf, strlen (buf));
301 /* Set up ACTION so that it is invoked on C stack overflow. Return -1
302 (setting errno) if this cannot be done.
304 When ACTION is called, it is passed an argument equal to SIGSEGV
305 for a segmentation violation that does not appear related to stack
306 overflow, and is passed zero otherwise. On many platforms it is
307 hard to tell; when in doubt, zero is passed.
309 A null ACTION acts like an action that does nothing.
311 ACTION must be async-signal-safe. ACTION together with its callees
312 must not require more than SIGSTKSZ bytes of stack space. Also,
313 ACTION should not call longjmp, because this implementation does
314 not guarantee that it is safe to return to the original stack. */
317 c_stack_action (void (*action) (int))
321 struct sigaction act;
323 st.ss_sp = alternate_signal_stack.buffer;
324 st.ss_size = sizeof alternate_signal_stack.buffer;
325 r = sigaltstack (&st, NULL);
329 segv_action = action ? action : null_action;
330 program_error_message = _("program error");
331 stack_overflow_message = _("stack overflow");
333 sigemptyset (&act.sa_mask);
336 /* POSIX 1003.1-2001 says SA_RESETHAND implies SA_NODEFER, but
337 this is not true on Solaris 8 at least. It doesn't hurt to use
338 SA_NODEFER here, so leave it in. */
339 act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO;
340 act.sa_sigaction = segv_handler;
342 act.sa_flags = SA_NODEFER | SA_RESETHAND;
343 act.sa_handler = die;
346 return sigaction (SIGSEGV, &act, NULL);
349 #else /* ! ((HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK) || HAVE_LIBSIGSEGV) */
352 c_stack_action (void (*action) (int) __attribute__ ((unused)))