about summary refs log tree commit diff
path: root/dlfcn/dlerror.c
diff options
context:
space:
mode:
Diffstat (limited to 'dlfcn/dlerror.c')
-rw-r--r--dlfcn/dlerror.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c
index 27376582d0..ca42c126c1 100644
--- a/dlfcn/dlerror.c
+++ b/dlfcn/dlerror.c
@@ -72,9 +72,16 @@ __dlerror (void)
   __libc_once (once, init);
 
   /* Get error string.  */
-  result = (struct dl_action_result *) __libc_getspecific (key);
-  if (result == NULL)
-    result = &last_result;
+  if (static_buf != NULL)
+    result = static_buf;
+  else
+    {
+      /* init () has been run and we don't use the static buffer.
+	 So we have a valid key.  */
+      result = (struct dl_action_result *) __libc_getspecific (key);
+      if (result == NULL)
+	result = &last_result;
+    }
 
   /* Test whether we already returned the string.  */
   if (result->returned != 0)
@@ -230,13 +237,19 @@ free_key_mem (void *mem)
 void
 __dlerror_main_freeres (void)
 {
-  void *mem;
   /* Free the global memory if used.  */
   check_free (&last_result);
-  /* Free the TSD memory if used.  */
-  mem = __libc_getspecific (key);
-  if (mem != NULL)
-    free_key_mem (mem);
+
+  if (__libc_once_get (once) && static_buf == NULL)
+    {
+      /* init () has been run and we don't use the static buffer.
+	 So we have a valid key.  */
+      void *mem;
+      /* Free the TSD memory if used.  */
+      mem = __libc_getspecific (key);
+      if (mem != NULL)
+	free_key_mem (mem);
+    }
 }
 
 struct dlfcn_hook *_dlfcn_hook __attribute__((nocommon));