Include sys/time.h.
[gnulib.git] / lib / c-stack.c
1 /* Stack overflow handling.
2
3    Copyright (C) 2002 Free Software Foundation, Inc.
4
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 2, or (at your option)
8    any later version.
9
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.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software Foundation,
17    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
18
19 /* Written by Paul Eggert.  */
20
21 /* NOTES:
22
23    A program that uses alloca, dynamic arrays, or large local
24    variables may extend the stack by more than a page at a time.  If
25    so, when the stack overflows the operating system may not detect
26    the overflow until the program uses the array, and this module may
27    incorrectly report a program error instead of a stack overflow.
28
29    To avoid this problem, allocate only small objects on the stack; a
30    program should be OK if it limits single allocations to a page or
31    less.  Allocate larger arrays in static storage, or on the heap
32    (e.g., with malloc).  Yes, this is a pain, but we don't know of any
33    better solution that is portable.
34
35    No attempt has been made to deal with multithreaded applications.
36
37    If ! HAVE_XSI_STACK_OVERFLOW_HEURISTIC, the current implementation
38    assumes that, if the RLIMIT_STACK limit changes during execution,
39    then c_stack_action is invoked immediately afterwards.  */
40
41 #if HAVE_CONFIG_H
42 # include <config.h>
43 #endif
44
45 #ifndef __attribute__
46 # if __GNUC__ < 3 || __STRICT_ANSI__
47 #  define __attribute__(x)
48 # endif
49 #endif
50
51 #include "gettext.h"
52 #define _(msgid) gettext (msgid)
53
54 #include <errno.h>
55 #ifndef ENOTSUP
56 # define ENOTSUP EINVAL
57 #endif
58 #ifndef EOVERFLOW
59 # define EOVERFLOW EINVAL
60 #endif
61
62 #include <signal.h>
63 #if ! HAVE_STACK_T && ! defined stack_t
64 typedef struct sigaltstack stack_t;
65 #endif
66
67 #include <stdlib.h>
68 #include <string.h>
69
70 #if HAVE_SYS_RESOURCE_H
71 /* Include sys/time.h here, because...
72    SunOS-4.1.x <sys/resource.h> fails to include <sys/time.h>.
73    This gives "incomplete type" errors for ru_utime and tu_stime.  */
74 # if HAVE_SYS_TIME_H
75 #  include <sys/time.h>
76 # endif
77 # include <sys/resource.h>
78 #endif
79
80 #if HAVE_UCONTEXT_H
81 # include <ucontext.h>
82 #endif
83
84 #if HAVE_UNISTD_H
85 # include <unistd.h>
86 #endif
87 #ifndef STDERR_FILENO
88 # define STDERR_FILENO 2
89 #endif
90
91 #if DEBUG
92 # include <stdio.h>
93 #endif
94
95 #include "c-stack.h"
96 #include "exitfail.h"
97
98 extern char *program_name;
99
100 /* The user-specified action to take when a SEGV-related program error
101    or stack overflow occurs.  */
102 static void (* volatile segv_action) (int);
103
104 /* Translated messages for program errors and stack overflow.  Do not
105    translate them in the signal handler, since gettext is not
106    async-signal-safe.  */
107 static char const * volatile program_error_message;
108 static char const * volatile stack_overflow_message;
109
110 /* Output an error message, then exit with status EXIT_FAILURE if it
111    appears to have been a stack overflow, or with a core dump
112    otherwise.  This function is async-signal-safe.  */
113
114 static void die (int) __attribute__ ((noreturn));
115 static void
116 die (int signo)
117 {
118   char const *message =
119     signo ? program_error_message : stack_overflow_message;
120   segv_action (signo);
121   write (STDERR_FILENO, program_name, strlen (program_name));
122   write (STDERR_FILENO, ": ", 2);
123   write (STDERR_FILENO, message, strlen (message));
124   write (STDERR_FILENO, "\n", 1);
125   if (! signo)
126     _exit (exit_failure);
127   kill (getpid (), signo);
128   abort ();
129 }
130
131 #if HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK
132
133 /* Direction of the C runtime stack.  This function is
134    async-signal-safe.  */
135
136 # if STACK_DIRECTION
137 #  define find_stack_direction(ptr) STACK_DIRECTION
138 # else
139 static int
140 find_stack_direction (char const *addr)
141 {
142   char dummy;
143   return ! addr ? find_stack_direction (&dummy) : addr < &dummy ? 1 : -1;
144 }
145 # endif
146
147 # if HAVE_XSI_STACK_OVERFLOW_HEURISTIC
148 #  define get_stack_location(argv) 0
149 # else
150
151 #  if defined RLIMIT_STACK && defined _SC_PAGESIZE
152
153 /* Return the minimum machine address deducible from ARGV.  This
154    includes the addresses of all the strings that ARGV points at, as
155    well as the address of ARGV itself.  */
156
157 static char const *
158 min_address_from_argv (char * const *argv)
159 {
160   char const *min = (char const *) argv;
161   char const *p;
162   while ((p = *argv++))
163     if (p < min)
164       min = p;
165   return min;
166 }
167
168 /* Return the maximum machine address deducible from ARGV.  */
169
170 static char const *
171 max_address_from_argv (char * const *argv)
172 {
173   char const *max = *argv;
174   char const *max1;
175   char const *p;
176   while ((p = *argv++))
177     if (max < p)
178       max = p;
179   max1 = (char const *) (argv + 1);
180   return max && max1 < max ? max + strlen (max) + 1 : max1;
181 }
182 #  endif
183
184 /* The base and size of the stack, determined at startup.  */
185 static char const * volatile stack_base;
186 static size_t volatile stack_size;
187
188 /* Store the base and size of the stack into the static variables
189    STACK_BASE and STACK_SIZE.  The base is the numerically lowest
190    address in the stack.  Return -1 (setting errno) if this cannot be
191    done.  */
192
193 static int
194 get_stack_location (char * const *argv)
195 {
196 #  if ! (defined RLIMIT_STACK && defined _SC_PAGESIZE)
197
198   errno = ENOTSUP;
199   return -1;
200
201 #  else
202
203   struct rlimit rlimit;
204   int r = getrlimit (RLIMIT_STACK, &rlimit);
205   if (r == 0)
206     {
207       char const *base;
208       size_t size = rlimit.rlim_cur;
209       extern char **environ;
210       size_t page_size = sysconf (_SC_PAGESIZE);
211       int stack_direction = find_stack_direction (0);
212
213 #   if HAVE_GETCONTEXT && HAVE_DECL_GETCONTEXT
214       ucontext_t context;
215       if (getcontext (&context) == 0)
216         {
217           base = context.uc_stack.ss_sp;
218           if (stack_direction < 0)
219             base -= size - context.uc_stack.ss_size;
220         }
221       else
222 #   endif
223         {
224           if (stack_direction < 0)
225             {
226               char const *a = max_address_from_argv (argv);
227               char const *b = max_address_from_argv (environ);
228               base = (a < b ? b : a) - size;
229               base += - (size_t) base % page_size;
230             }
231           else
232             {
233               char const *a = min_address_from_argv (argv);
234               char const *b = min_address_from_argv (environ);
235               base = a < b ? a : b;
236               base -= (size_t) base % page_size;
237             }
238         }
239
240       if (size != rlimit.rlim_cur
241           || rlimit.rlim_cur < 0
242           || base + size < base
243 #   ifdef RLIM_SAVED_CUR
244           || rlimit.rlim_cur == RLIM_SAVED_CUR
245 #   endif
246 #   ifdef RLIM_SAVED_MAX
247           || rlimit.rlim_cur == RLIM_SAVED_MAX
248 #   endif
249 #   ifdef RLIM_INFINITY
250           || rlimit.rlim_cur == RLIM_INFINITY
251 #   endif
252           )
253         {
254           errno = EOVERFLOW;
255           return -1;
256         }
257
258       stack_base = base;
259       stack_size = size;
260
261 #   if DEBUG
262       fprintf (stderr, "get_stack_location base=%p size=%lx\n",
263                base, (unsigned long) size);
264 #   endif
265     }
266
267   return r;
268
269 #  endif
270 }
271 # endif
272
273 /* Storage for the alternate signal stack.  */
274 static union
275 {
276   char buffer[SIGSTKSZ];
277
278   /* These other members are for proper alignment.  There's no
279      standard way to guarantee stack alignment, but this seems enough
280      in practice.  */
281   long double ld;
282   long l;
283   void *p;
284 } alternate_signal_stack;
285
286 # if defined SA_ONSTACK && defined SA_SIGINFO && defined _SC_PAGESIZE
287
288 /* Handle a segmentation violation and exit.  This function is
289    async-signal-safe.  */
290
291 static void segv_handler (int, siginfo_t *, void *) __attribute__((noreturn));
292 static void
293 segv_handler (int signo, siginfo_t *info,
294               void *context __attribute__ ((unused)))
295 {
296   /* Clear SIGNO if it seems to have been a stack overflow.  */
297   if (0 < info->si_code)
298     {
299       /* If the faulting address is within the stack, or within one
300          page of the stack end, assume that it is a stack
301          overflow.  */
302 #  if HAVE_XSI_STACK_OVERFLOW_HEURISTIC
303       ucontext_t const *user_context = context;
304       char const *stack_base = user_context->uc_stack.ss_sp;
305       size_t stack_size = user_context->uc_stack.ss_size;
306 #  endif
307       char const *faulting_address = info->si_addr;
308       size_t s = faulting_address - stack_base;
309       size_t page_size = sysconf (_SC_PAGESIZE);
310       if (find_stack_direction (0) < 0)
311         s += page_size;
312       if (s < stack_size + page_size)
313         signo = 0;
314
315 #  if DEBUG
316       {
317         char buf[1024];
318         sprintf (buf,
319                  "segv_handler fault=%p base=%p size=%lx page=%lx signo=%d\n",
320                  faulting_address, stack_base, (unsigned long) stack_size,
321                  (unsigned long) page_size, signo);
322         write (STDERR_FILENO, buf, strlen (buf));
323       }
324 #  endif
325     }
326
327   die (signo);
328 }
329 # endif
330
331 static void
332 null_action (int signo __attribute__ ((unused)))
333 {
334 }
335
336 /* Assuming ARGV is the argument vector of `main', set up ACTION so
337    that it is invoked on C stack overflow.  Return -1 (setting errno)
338    if this cannot be done.
339
340    When ACTION is called, it is passed an argument equal to SIGSEGV
341    for a segmentation violation that does not appear related to stack
342    overflow, and is passed zero otherwise.
343
344    A null ACTION acts like an action that does nothing.
345
346    ACTION must be async-signal-safe.  ACTION together with its callees
347    must not require more than SIGSTKSZ bytes of stack space.  */
348
349 int
350 c_stack_action (char * const *argv __attribute__ ((unused)),
351                 void (*action) (int))
352 {
353   int r = get_stack_location (argv);
354   if (r != 0)
355     return r;
356
357   {
358     stack_t st;
359     st.ss_flags = 0;
360     st.ss_sp = alternate_signal_stack.buffer;
361     st.ss_size = sizeof alternate_signal_stack.buffer;
362     r = sigaltstack (&st, 0);
363     if (r != 0)
364       return r;
365   }
366
367   segv_action = action ? action : null_action;
368   program_error_message = _("program error");
369   stack_overflow_message = _("stack overflow");
370
371   {
372 # if ! (defined SA_ONSTACK && defined SA_SIGINFO && defined _SC_PAGESIZE)
373     return signal (SIGSEGV, die) == SIG_ERR ? -1 : 0;
374 # else
375     struct sigaction act;
376     sigemptyset (&act.sa_mask);
377
378     /* POSIX 1003.1-2001 says SA_RESETHAND implies SA_NODEFER, but
379        this is not true on Solaris 8 at least.  It doesn't hurt to use
380        SA_NODEFER here, so leave it in.  */
381     act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO;
382
383     act.sa_sigaction = segv_handler;
384
385     return sigaction (SIGSEGV, &act, 0);
386 # endif
387   }
388 }
389
390 #else /* ! (HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK) */
391
392 int
393 c_stack_action (char * const *argv __attribute__ ((unused)),
394                 void (*action) (int)  __attribute__ ((unused)))
395 {
396   errno = ENOTSUP;
397   return -1;
398 }
399
400 #endif
401
402 \f
403
404 #if DEBUG
405
406 int volatile exit_failure;
407
408 static long
409 recurse (char *p)
410 {
411   char array[500];
412   array[0] = 1;
413   return *p + recurse (array);
414 }
415
416 char *program_name;
417
418 int
419 main (int argc __attribute__ ((unused)), char **argv)
420 {
421   program_name = argv[0];
422   fprintf (stderr, "The last line of output should be \"stack overflow\".\n");
423   if (c_stack_action (argv, 0) == 0)
424     return recurse ("\1");
425   perror ("c_stack_action");
426   return 1;
427 }
428
429 #endif /* DEBUG */
430 \f
431 /*
432 Local Variables:
433 compile-command: "gcc -DDEBUG -DHAVE_CONFIG_H -I.. -g -O -Wall -W c-stack.c"
434 End:
435 */