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