This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc 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] Remove Linuxism from tst-tls-atexit


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.

	* 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 | 53 ++++++++++++++++++++++++++++++++-----------------
 1 file changed, 35 insertions(+), 18 deletions(-)

diff --git a/stdlib/tst-tls-atexit.c b/stdlib/tst-tls-atexit.c
index 974264d..16b208d 100644
--- a/stdlib/tst-tls-atexit.c
+++ b/stdlib/tst-tls-atexit.c
@@ -27,10 +27,20 @@
 #include <unistd.h>
 #include <string.h>
 #include <errno.h>
+#include <setjmp.h>
 
-void *handle;
+static void *handle;
+static void (*foo) (void);
+static jmp_buf env;
 
-void *
+static void
+segv_handler (int sig)
+{
+  /* All good. */
+  longjmp (env, 1);
+}
+
+static void *
 load (void *u)
 {
   handle = dlopen ("$ORIGIN/tst-tls-atexit-lib.so", RTLD_LAZY);
@@ -40,7 +50,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 +92,36 @@ 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 (setjmp (env) != 0)
     {
-      if (strstr (line, "tst-tls-atexit-lib.so"))
-        {
-	  printf ("DSO not unloaded yet:\n%s", line);
+      /* Restore the default handler so that we may catch any SIGSEGVs
+	 later.  */
+      if (sigaction (SIGSEGV, &old_sa, NULL) < 0)
+	{
+	  printf ("Failed to restore SIGSEGV handler: %m\n");
 	  return 1;
 	}
+
+      return 0;
     }
-  free (line);
 
-  return 0;
+  /* This should crash...  */
+  foo ();
+
+  /* ... or else we fail.  */
+  return 1;
 }
 
 #define TEST_FUNCTION do_test ()
-- 
2.4.3


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