00db10
Based on the following commits:
00db10
00db10
commit 2c41b52901331f5c761015af786a3976e225d779
00db10
Author: Florian Weimer <fweimer@redhat.com>
00db10
Date:   Mon Jun 13 13:08:39 2016 +0200
00db10
00db10
    debug/tst-longjmp_chk2: Make signal handler more conservative [BZ #20248]
00db10
    
00db10
    Currently, printf needs more stack space than what is available with
00db10
    SIGSTKSZ.  This commit use the the write system call directly instead.
00db10
    
00db10
    Also use sig_atomic_t for the “pass” variable (for general
00db10
    correctness), and restore signal handlers to their defaults, to avoid
00db10
    masking crashes.
00db10
00db10
commit 5896c8bdd9f73cdc816a96e107ca1f7a6bc6921e
00db10
Author: Mike Frysinger <vapier@gentoo.org>
00db10
Date:   Sun Dec 29 16:30:35 2013 -0500
00db10
00db10
    tst-longjmp_chk2: add comments/sanity check
00db10
    
00db10
    If the longjmp checking code is slightly broken, this code can loop
00db10
    forever which isn't too helpful.  Add a sanity check to keep that
00db10
    from happening.
00db10
    
00db10
    Signed-off-by: Mike Frysinger <vapier@gentoo.org>
00db10
00db10
Index: b/debug/tst-longjmp_chk2.c
00db10
===================================================================
00db10
--- a/debug/tst-longjmp_chk2.c
00db10
+++ b/debug/tst-longjmp_chk2.c
00db10
@@ -4,27 +4,36 @@
00db10
 #include <signal.h>
00db10
 #include <stdio.h>
00db10
 #include <stdlib.h>
00db10
+#include <string.h>
00db10
 #include <sys/types.h>
00db10
 #include <sys/time.h>
00db10
 #include <sys/resource.h>
00db10
+#include <unistd.h>
00db10
 
00db10
 
00db10
 static jmp_buf mainloop;
00db10
 static sigset_t mainsigset;
00db10
-static int pass;
00db10
+static volatile sig_atomic_t pass;
00db10
 
00db10
+static void
00db10
+write_message (const char *message)
00db10
+{
00db10
+  ssize_t unused __attribute__ ((unused));
00db10
+  for (int i = 0; i < pass; ++i)
00db10
+    unused = write (STDOUT_FILENO, " ", 1);
00db10
+  unused = write (STDOUT_FILENO, message, strlen (message));
00db10
+}
00db10
 
00db10
 static void
00db10
 stackoverflow_handler (int sig)
00db10
 {
00db10
   stack_t altstack;
00db10
   pass++;
00db10
+  assert (pass < 5);
00db10
   sigaltstack (NULL, &altstack);
00db10
-  /* Using printf is not really kosher in signal handlers but we know
00db10
-     it will work.  */
00db10
-  printf ("%*sin signal handler\n", pass, "");
00db10
+  write_message ("in signal handler\n");
00db10
   if (altstack.ss_flags & SS_ONSTACK)
00db10
-    printf ("%*son alternate stack\n", pass, "");
00db10
+    write_message ("on alternate stack\n");
00db10
   siglongjmp (mainloop, pass);
00db10
 }
00db10
 
00db10
@@ -107,6 +116,11 @@ do_test (void)
00db10
   else
00db10
     printf ("disabling alternate stack succeeded \n");
00db10
 
00db10
+  /* Restore the signal handlers, in case we trigger a crash after the
00db10
+     tests above.  */
00db10
+  signal (SIGBUS, SIG_DFL);
00db10
+  signal (SIGSEGV, SIG_DFL);
00db10
+
00db10
   return 0;
00db10
 }
00db10