X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fc-stack.c;h=46575489de96688c3e0fa22a3fa644511b591a83;hb=fef5e6b4fc847bb1c01a20314effae7cb7828f38;hp=023f8479ae3219fd111931c060bf8aef4047cb63;hpb=732ef44992c7a5a6b4dd74ea5e5ddaab18bb1b86;p=gnulib.git diff --git a/lib/c-stack.c b/lib/c-stack.c index 023f8479a..46575489d 100644 --- a/lib/c-stack.c +++ b/lib/c-stack.c @@ -1,6 +1,7 @@ /* Stack overflow handling. - Copyright (C) 2002, 2004, 2006, 2008 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2006, 2008, 2009, 2010 Free Software Foundation, + Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -45,9 +46,6 @@ #define _(msgid) gettext (msgid) #include -#ifndef ENOTSUP -# define ENOTSUP EINVAL -#endif #include #if ! HAVE_STACK_T && ! defined stack_t @@ -67,9 +65,6 @@ typedef struct sigaltstack stack_t; #endif #include -#ifndef STDERR_FILENO -# define STDERR_FILENO 2 -#endif #if HAVE_LIBSIGSEGV # include @@ -77,6 +72,7 @@ typedef struct sigaltstack stack_t; #include "c-stack.h" #include "exitfail.h" +#include "ignore-value.h" #if defined SA_ONSTACK && defined SA_SIGINFO # define SIGACTION_WORKS 1 @@ -110,10 +106,10 @@ die (int signo) char const *message; segv_action (signo); message = signo ? program_error_message : stack_overflow_message; - write (STDERR_FILENO, program_name, strlen (program_name)); - write (STDERR_FILENO, ": ", 2); - write (STDERR_FILENO, message, strlen (message)); - write (STDERR_FILENO, "\n", 1); + ignore_value (write (STDERR_FILENO, program_name, strlen (program_name))); + ignore_value (write (STDERR_FILENO, ": ", 2)); + ignore_value (write (STDERR_FILENO, message, strlen (message))); + ignore_value (write (STDERR_FILENO, "\n", 1)); if (! signo) _exit (exit_failure); raise (signo); @@ -155,7 +151,7 @@ static volatile int segv_handler_missing; overflow. This function is async-signal-safe. */ static int segv_handler (void *address __attribute__ ((unused)), - int serious) + int serious) { # if DEBUG { @@ -179,13 +175,13 @@ static void overflow_handler (int, stackoverflow_context_t) __attribute__ ((noreturn)); static void overflow_handler (int emergency, - stackoverflow_context_t context __attribute__ ((unused))) + stackoverflow_context_t context __attribute__ ((unused))) { # if DEBUG { char buf[1024]; sprintf (buf, "overflow_handler emergency=%d segv_handler_missing=%d\n", - emergency, segv_handler_missing); + emergency, segv_handler_missing); write (STDERR_FILENO, buf, strlen (buf)); } # endif @@ -222,12 +218,14 @@ c_stack_action (void (*action) (int)) # if STACK_DIRECTION # define find_stack_direction(ptr) STACK_DIRECTION # else +# if ! SIGACTION_WORKS || HAVE_XSI_STACK_OVERFLOW_HEURISTIC static int find_stack_direction (char const *addr) { char dummy; return ! addr ? find_stack_direction (&dummy) : addr < &dummy ? 1 : -1; } +# endif # endif # if SIGACTION_WORKS @@ -238,27 +236,27 @@ find_stack_direction (char const *addr) static void segv_handler (int, siginfo_t *, void *) __attribute__((noreturn)); static void segv_handler (int signo, siginfo_t *info, - void *context __attribute__ ((unused))) + void *context __attribute__ ((unused))) { /* Clear SIGNO if it seems to have been a stack overflow. */ - if (0 < info->si_code) - { # if ! HAVE_XSI_STACK_OVERFLOW_HEURISTIC - /* We can't easily determine whether it is a stack overflow; so - assume that the rest of our program is perfect (!) and that - this segmentation violation is a stack overflow. - - Note that although both Linux and Solaris provide - sigaltstack, SA_ONSTACK, and SA_SIGINFO, currently only - Solaris satisfies the XSI heueristic. This is because - Solaris populates uc_stack with the details of the - interrupted stack, while Linux populates it with the details - of the current stack. */ - signo = 0; + /* We can't easily determine whether it is a stack overflow; so + assume that the rest of our program is perfect (!) and that + this segmentation violation is a stack overflow. + + Note that although both Linux and Solaris provide + sigaltstack, SA_ONSTACK, and SA_SIGINFO, currently only + Solaris satisfies the XSI heueristic. This is because + Solaris populates uc_stack with the details of the + interrupted stack, while Linux populates it with the details + of the current stack. */ + signo = 0; # else + if (0 < info->si_code) + { /* If the faulting address is within the stack, or within one - page of the stack end, assume that it is a stack - overflow. */ + page of the stack end, assume that it is a stack + overflow. */ ucontext_t const *user_context = context; char const *stack_base = user_context->uc_stack.ss_sp; size_t stack_size = user_context->uc_stack.ss_size; @@ -266,22 +264,22 @@ segv_handler (int signo, siginfo_t *info, size_t s = faulting_address - stack_base; size_t page_size = sysconf (_SC_PAGESIZE); if (find_stack_direction (NULL) < 0) - s += page_size; + s += page_size; if (s < stack_size + page_size) - signo = 0; + signo = 0; # if DEBUG { - char buf[1024]; - sprintf (buf, - "segv_handler fault=%p base=%p size=%lx page=%lx signo=%d\n", - faulting_address, stack_base, (unsigned long) stack_size, - (unsigned long) page_size, signo); - write (STDERR_FILENO, buf, strlen (buf)); + char buf[1024]; + sprintf (buf, + "segv_handler fault=%p base=%p size=%lx page=%lx signo=%d\n", + faulting_address, stack_base, (unsigned long) stack_size, + (unsigned long) page_size, signo); + write (STDERR_FILENO, buf, strlen (buf)); } # endif -# endif } +# endif die (signo); } @@ -332,7 +330,7 @@ c_stack_action (void (*action) (int)) } #else /* ! ((HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK - && HAVE_STACK_OVERFLOW_HANDLING) || HAVE_LIBSIGSEGV) */ + && HAVE_STACK_OVERFLOW_HANDLING) || HAVE_LIBSIGSEGV) */ int c_stack_action (void (*action) (int) __attribute__ ((unused)))