[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: c-stack and Irix - libsigsegv
From: |
Eric Blake |
Subject: |
Re: c-stack and Irix - libsigsegv |
Date: |
Sat, 20 Sep 2008 22:07:17 -0600 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.16) Gecko/20080708 Thunderbird/2.0.0.16 Mnenhy/0.7.5.666 |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
According to Eric Blake on 9/16/2008 4:50 PM:
> I've finally figured out why c-stack is being finicky on Irix 5.3 [1]. POSIX
> requires that sigaltstack be given ss_sp pointing to the smallest address in
> the alternate stack. But Irix is non-compliant, and treats ss_sp as the
> starting address of the stack (which, since it grows down, makes it the
> largest
> address in the stack).
Here's the minimal patch needed to CVS libsigsegv to expose the bug, as
well as work around it for Irix 5.3. I still need to port something like
this for c-stack in the non-libsigsegv case.
2008-09-20 Eric Blake <address@hidden>
Detect and work around bug in Irix 5.3 sigaltstack.
* m4/sigaltstack.m4 (SV_SIGALTSTACK): Test for broken stack
direction in sigaltstack.
* src/handler-unix.c (stackoverflow_install_handler): Adjust stack
accordingly.
* tests/stackoverflow1.c (stack_base): New variable.
(check_stack_location): Additional check.
(stackoverflow_handler, main): Use them to expose Irix bug.
- --
Don't work too hard, make some time for fun as well!
Eric Blake address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iEYEARECAAYFAkjVyHUACgkQ84KuGfSFAYCqfACffIR5b0vf+h21B7BAPtOxPPHW
/BgAniTKRbidmw4ocOIrS5qJnwik1Nj5
=EbMO
-----END PGP SIGNATURE-----
Index: src/handler-unix.c
===================================================================
RCS file: /sources/libsigsegv/libsigsegv/src/handler-unix.c,v
retrieving revision 1.8
diff -u -p -r1.8 handler-unix.c
--- src/handler-unix.c 24 Aug 2008 13:54:16 -0000 1.8
+++ src/handler-unix.c 21 Sep 2008 04:06:19 -0000
@@ -487,6 +487,11 @@ stackoverflow_install_handler (stackover
{
stack_t ss;
ss.ss_sp = extra_stack;
+# if !SIGALTSTACK_LOW_BASE
+ /* Some platforms, such as Irix 5.3, mistakenly treat ss_sp as the
+ upper bound of the alternate stack. */
+ ss.ss_sp += SIGSTKSZ - 1;
+# endif
ss.ss_size = extra_stack_size;
ss.ss_flags = 0; /* no SS_DISABLE */
if (sigaltstack (&ss, (stack_t*)0) < 0)
Index: tests/stackoverflow1.c
===================================================================
RCS file: /sources/libsigsegv/libsigsegv/tests/stackoverflow1.c,v
retrieving revision 1.10
diff -u -p -r1.10 stackoverflow1.c
--- tests/stackoverflow1.c 24 Aug 2008 20:55:17 -0000 1.10
+++ tests/stackoverflow1.c 21 Sep 2008 04:06:19 -0000
@@ -49,6 +49,14 @@ jmp_buf mainloop;
sigset_t mainsigset;
volatile int pass = 0;
+volatile char *stack_base;
+
+static void
+check_stack_location (volatile char *addr)
+{
+ if (addr < stack_base || addr >= stack_base + SIGSTKSZ)
+ abort ();
+}
static void
stackoverflow_handler_continuation (void *arg1, void *arg2, void *arg3)
@@ -60,6 +68,11 @@ stackoverflow_handler_continuation (void
void
stackoverflow_handler (int emergency, stackoverflow_context_t scp)
{
+ if (pass == 0)
+ {
+ char dummy;
+ check_stack_location (&dummy);
+ }
pass++;
printf ("Stack overflow %d caught.\n", pass);
sigprocmask (SIG_SETMASK, &mainsigset, NULL);
@@ -99,6 +112,7 @@ main ()
#endif
/* Install the stack overflow handler. */
+ stack_base = mystack;
if (stackoverflow_install_handler (&stackoverflow_handler,
mystack, sizeof (mystack))
< 0)
Index: m4/sigaltstack.m4
===================================================================
RCS file: /sources/libsigsegv/libsigsegv/m4/sigaltstack.m4,v
retrieving revision 1.11
diff -u -p -r1.11 sigaltstack.m4
--- m4/sigaltstack.m4 24 Aug 2008 20:55:08 -0000 1.11
+++ m4/sigaltstack.m4 21 Sep 2008 04:06:19 -0000
@@ -1,4 +1,4 @@
-# sigaltstack.m4 serial 8 (libsigsegv-2.6)
+# sigaltstack.m4 serial 9 (libsigsegv-2.7)
dnl Copyright (C) 2002-2006, 2008 Bruno Haible <address@hidden>
dnl This file is free software, distributed under the terms of the GNU
dnl General Public License. As a special exception to the GNU General
@@ -123,5 +123,64 @@ int main ()
if test "$sv_cv_sigaltstack" != no; then
AC_DEFINE(HAVE_WORKING_SIGALTSTACK, 1,
[Define if you have the sigaltstack() function and it works.])
+ AC_CACHE_CHECK([for correct sigaltstack boundary],
+ [sv_cv_sigaltstack_low_base], [
+ AC_RUN_IFELSE([
+ AC_LANG_SOURCE([[
+#include <stdlib.h>
+#include <signal.h>
+#if HAVE_SYS_SIGNAL_H
+# include <sys/signal.h>
+#endif
+#ifndef SIGSTKSZ
+# define SIGSTKSZ 16384
+#endif
+volatile char *stack_base;
+static void check_stack_location (volatile char *addr)
+{
+ if (addr >= stack_base && addr < stack_base + SIGSTKSZ)
+ exit (0);
+}
+void stackoverflow_handler (int sig)
+{
+ char dummy;
+ check_stack_location (&dummy);
+ exit (1);
+}
+int main ()
+{
+ char mystack[SIGSTKSZ];
+ stack_t altstack;
+ struct sigaction action;
+ /* Install the alternate stack. */
+ stack_base = altstack.ss_sp = mystack;
+ altstack.ss_size = sizeof (mystack);
+ altstack.ss_flags = 0; /* no SS_DISABLE */
+ if (sigaltstack (&altstack, NULL) < 0)
+ exit (1);
+ /* Install the SIGSEGV handler. */
+ sigemptyset (&action.sa_mask);
+ action.sa_handler = &stackoverflow_handler;
+ action.sa_flags = SA_ONSTACK;
+ sigaction (SIGSEGV, &action, (struct sigaction *) NULL);
+ /* Provoke a SIGSEGV. */
+ raise (SIGSEGV);
+ exit (2);
+}]])],
+ [sv_cv_sigaltstack_low_base=yes],
+ [sv_cv_sigaltstack_low_base=no],
+ [
+ dnl FIXME: Put in some more known values here.
+ case "$host_os" in
+ irix5*) sv_cv_sigaltstack_low_base="no" ;;
+ *) sv_cv_sigaltstack_low_base="guessing yes" ;;
+ esac
+ ])
+ ])
+ if test "$sv_cv_sigaltstack_low_base" != no; then
+ AC_DEFINE([SIGALTSTACK_LOW_BASE], [1],
+ [Define if sigaltstack() obeys POSIX by interpreting the stack
+ base as the low address of a range, even if the stack grows down.])
+ fi
fi
])
Re: c-stack and Irix - gnulib, Eric Blake, 2008/09/23