This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PATCH COMMITTED: Fix relro_test when throwing from signal handler fails
- From: Ian Lance Taylor <iant at google dot com>
- To: binutils at sourceware dot org
- Date: Mon, 09 Jun 2008 12:14:47 -0700
- Subject: 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
{