This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH COMMITTED: Fix relro_test when throwing from signal handler fails


The relro_test works by triggering a segmentation violation, catching
it in a signal handler, and having the signal handler throw the
exception back to the test code.  That works with current gcc, but it
doesn't work with older versions of gcc.  I committed this patch so
that the test also passes if throwing from a signal handler winds up
calling terminate.

Ian


2008-06-09  Ian Lance Taylor  <iant@google.com>

	* testsuite/relro_test.cc: Include <cstdio>, <cstdlib>, and
	<exception>.
	(throwing, orig_terminate): New static variables.
	(terminate_handler): New static function.
	(t2): Set terminate handler.


Index: testsuite/relro_test.cc
===================================================================
RCS file: /cvs/src/src/gold/testsuite/relro_test.cc,v
retrieving revision 1.1
diff -u -p -r1.1 relro_test.cc
--- testsuite/relro_test.cc	20 May 2008 04:00:47 -0000	1.1
+++ testsuite/relro_test.cc	9 Jun 2008 19:10:47 -0000
@@ -22,6 +22,9 @@
 
 #include <cassert>
 #include <csignal>
+#include <cstdio>
+#include <cstdlib>
+#include <exception>
 #include <stdint.h>
 #include <unistd.h>
 
@@ -69,15 +72,42 @@ t1()
   return true;
 }
 
+// Tell terminate handler that we are throwing from a signal handler.
+
+static bool throwing;
+
 // A signal handler for SIGSEGV.
 
 extern "C"
 void
 sigsegv_handler(int)
 {
+  throwing = true;
   throw 0;
 }
 
+// The original terminate handler.
+
+std::terminate_handler orig_terminate;
+
+// Throwing an exception out of a signal handler doesn't always work
+// reliably.  When that happens the program will call terminate.  We
+// set a terminate handler to indicate that the test probably passed.
+
+void
+terminate_handler()
+{
+  if (!throwing)
+    {
+      orig_terminate();
+      ::exit(EXIT_FAILURE);
+    }
+  fprintf(stderr,
+	  "relro_test: terminate called due to failure to throw through signal handler\n");
+  fprintf(stderr, "relro_test: assuming test succeeded\n");
+  ::exit(EXIT_SUCCESS);
+}
+
 // Use a separate function to throw the exception, so that we don't
 // need to use -fnon-call-exceptions.
 
@@ -100,6 +130,7 @@ bool
 t2()
 {
   signal(SIGSEGV, sigsegv_handler);
+  orig_terminate = std::set_terminate(terminate_handler);
 
   try
     {

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]