Using libunwind 1.1 on SLES with my own malloc tracer, I get a deadlock in various places, e.g.:

#0  0x00007f65311a2324 in __lll_lock_wait () from /lib64/libpthread.so.0

#1  0x00007f653119d669 in _L_lock_1008 () from /lib64/libpthread.so.0

#2  0x00007f653119d47e in pthread_mutex_lock () from /lib64/libpthread.so.0

#3  0x00007f6530c05622 in get_rs_cache (saved_maskp=<optimized out>,

    as=<optimized out>) at dwarf/Gparser.c:531

#4  _ULx86_64_dwarf_find_save_locs (c=0x7ffd68e96b10) at dwarf/Gparser.c:853

#5  0x00007f6530c05839 in _ULx86_64_dwarf_step (

    c=0x7f6530e0d220 <local_addr_space+96>) at dwarf/Gstep.c:34

#6  0x00007f6530c01dd4 in _ULx86_64_step (

    cursor=0x7f6530e0d220 <local_addr_space+96>) at x86_64/Gstep.c:71

#7  0x00007f65323ece20 in ml_backtrace (stk=0x8300fc0, stknum=24) at mleak.c:63

#8  0x00007f65323ed332 in malloc (size=25) at mleak.c:231

#9  0x00007f6537613f02 in local_strdup () from /lib64/ld-linux-x86-64.so.2

#10 0x00007f6537616c86 in _dl_map_object () from /lib64/ld-linux-x86-64.so.2

#11 0x00007f6537621400 in dl_open_worker () from /lib64/ld-linux-x86-64.so.2

#12 0x00007f653761ce86 in _dl_catch_error () from /lib64/ld-linux-x86-64.so.2

#13 0x00007f6537620e3b in _dl_open () from /lib64/ld-linux-x86-64.so.2

#14 0x00007f6531bbff9b in dlopen_doit () from /lib64/libdl.so.2

#15 0x00007f653761ce86 in _dl_catch_error () from /lib64/ld-linux-x86-64.so.2

#16 0x00007f6531bc033c in _dlerror_run () from /lib64/libdl.so.2

#17 0x00007f6531bbff01 in dlopen@@GLIBC_2.2.5 () from /lib64/libdl.so.2

The tracer is at https://github.com/hyc/mleak

I haven't been able to identify where get_rs_cache was called previously, but it strikes me that just using a recursive mutex would make this problem go away. See attached patch.

--
  -- Howard Chu
  CTO, Symas Corp.           http://www.symas.com
  Director, Highland Sun     http://highlandsun.com/hyc/
  Chief Architect, OpenLDAP  http://www.openldap.org/project/
diff --git a/src/x86_64/Ginit.c b/src/x86_64/Ginit.c
index 6e9d4fe..8c102be 100644
--- a/src/x86_64/Ginit.c
+++ b/src/x86_64/Ginit.c
@@ -264,6 +264,24 @@ x86_64_local_addr_space_init (void)
   local_addr_space.acc.get_proc_name = get_static_proc_name;
   unw_flush_cache (&local_addr_space, 0, 0);
 
+#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
+  {
+    static const pthread_mutex_t cachelock_init = 
PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+    local_addr_space.global_cache.lock = cachelock_init;
+  }
+#else
+#pragma weak pthread_mutexattr_init
+#pragma weak pthread_mutexattr_destroy
+#pragma weak pthread_mutex_init
+#pragma weak pthread_mutexattr_settype
+  if (pthread_mutex_init) {
+    pthread_mutexattr_t attr;
+    pthread_mutexattr_init(&attr);
+    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+    pthread_mutex_init(&local_addr_space.global_cache.lock, &attr);
+    pthread_mutexattr_destroy(&attr);
+  }
+#endif
   memset (last_good_addr, 0, sizeof (unw_word_t) * NLGA);
   lga_victim = 0;
 }
_______________________________________________
Libunwind-devel mailing list
Libunwind-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/libunwind-devel

Reply via email to