diff mbox

[v2] Remove Linuxism from tst-tls-atexit

Message ID 1436921918-3008-1-git-send-email-siddhesh@redhat.com
State New
Headers show

Commit Message

Siddhesh Poyarekar July 15, 2015, 12:58 a.m. UTC
The tst-tls-atexit test case searches for its module in /proc/PID/maps
to verify that it is unloaded, which is a Linux-specific test.  This
patch makes the test generic by trying to call foo (the symbol
obtained from dlsym) and traps SIGSEGV momentarily to see if the crash
occurred.

Verified that the test continues to succeed on x86_64.  There is a bug
in the test case where it calls dlclose once again, which is actually
incorrect but still manages to unload the DSO thanks to an existing
bug in __tls_call_dtors.  This will be fixed in a later patch which
also fixes up the __cxa_thread_atexit_impl implementation.

v2: Replaced setjmp/longjmp with a simple _exit.

	* stdlib/tst-tls-atexit.c: Include setjmp.h
	(foo): Move out from LOAD.
	(env): New variable.
	(segv_handler): New function.
	(load): Make static.
	(do_test): Install SIGSEGV handler and test for call to FOO.
---
 stdlib/tst-tls-atexit.c | 46 ++++++++++++++++++++++++----------------------
 1 file changed, 24 insertions(+), 22 deletions(-)
diff mbox

Patch

diff --git a/stdlib/tst-tls-atexit.c b/stdlib/tst-tls-atexit.c
index 0c6c499..cd3e2b3 100644
--- a/stdlib/tst-tls-atexit.c
+++ b/stdlib/tst-tls-atexit.c
@@ -28,9 +28,17 @@ 
 #include <string.h>
 #include <errno.h>
 
-void *handle;
+static void *handle;
+static void (*foo) (void);
 
-void *
+static void
+segv_handler (int sig)
+{
+  /* All good. */
+  _exit (0);
+}
+
+static void *
 load (void *u)
 {
   handle = dlopen ("$ORIGIN/tst-tls-atexit-lib.so", RTLD_LAZY);
@@ -40,7 +48,7 @@  load (void *u)
       return (void *) (uintptr_t) 1;
     }
 
-  void (*foo) (void) = (void (*) (void)) dlsym (handle, "do_foo");
+  foo = (void (*) (void)) dlsym (handle, "do_foo");
 
   if (foo == NULL)
     {
@@ -82,29 +90,23 @@  do_test (void)
   /* Now this should unload the DSO.  */
   dlclose (handle);
 
-  /* Run through our maps and ensure that the DSO is unloaded.  */
-  FILE *f = fopen ("/proc/self/maps", "r");
-
-  if (f == NULL)
+  /* Handle SIGSEGV.  We don't use the EXPECTED_SIGNAL macro because we want to
+     detect any other SIGSEGVs as failures.  */
+  struct sigaction sa, old_sa;
+  sa.sa_handler = segv_handler;
+  sigemptyset (&sa.sa_mask);
+  sa.sa_flags = 0;
+  if (sigaction (SIGSEGV, &sa, &old_sa) < 0)
     {
-      perror ("Failed to open /proc/self/maps");
-      fprintf (stderr, "Skipping verification of DSO unload\n");
-      return 0;
+      printf ("Failed to set SIGSEGV handler: %m\n");
+      return 1;
     }
 
-  char *line = NULL;
-  size_t s = 0;
-  while (getline (&line, &s, f) > 0)
-    {
-      if (strstr (line, "tst-tls-atexit-lib.so"))
-        {
-	  printf ("DSO not unloaded yet:\n%s", line);
-	  return 1;
-	}
-    }
-  free (line);
+  /* This should crash...  */
+  foo ();
 
-  return 0;
+  /* ... or else we fail.  */
+  return 1;
 }
 
 #define TEST_FUNCTION do_test ()