libunwind-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Libunwind-devel] [patch] Allow for complete stack traces even when othe


From: Paul Pluzhnikov
Subject: [Libunwind-devel] [patch] Allow for complete stack traces even when other threads iterfere.
Date: Mon, 21 Sep 2009 13:52:21 -0700 (PDT)

Greetings,

Currently, libunwind may "give up" and produce an incomplete stack trace
if two threads are both using libunwind to collect their stack traces.

Attached patch implements a new configure option --enable-cache-wait,
which lets libunwind to wait for dwarf cache to become available.

Thanks,

--
Paul Pluzhnikov

commit f7c22c16a0640f63c22a79864ca136cb9820f97e
Author: Paul Pluzhnikov <address@hidden>
Date:   Mon Sep 21 13:25:57 2009 -0700

    New configure option: when rs_cache is busy in another thread, wait for it.

diff --git a/configure.in b/configure.in
index 6e55563..57254c2 100644
--- a/configure.in
+++ b/configure.in
@@ -146,6 +146,12 @@ if test x$enable_block_signals = xyes; then
   AC_DEFINE([CONFIG_BLOCK_SIGNALS], [], [Block signals before mutex 
operations])
 fi
 
+AC_ARG_ENABLE(cache_wait,
+[  --enable-cache-wait Wait for cache, rather than giving incomplete stack],
+[enable_cache_wait=$enableval], [enable_cache_wait=no])
+if test x$enable_cache_wait = xyes; then
+  AC_DEFINE([CONFIG_CACHE_WAIT], [], [Wait for cache])
+fi
 
 LIBUNWIND___THREAD
 
diff --git a/include/dwarf.h b/include/dwarf.h
index c7c757e..cf0cf5a 100644
--- a/include/dwarf.h
+++ b/include/dwarf.h
@@ -312,7 +312,8 @@ typedef unsigned char unw_hash_index_t;
 
 struct dwarf_rs_cache
   {
-#ifdef HAVE_ATOMIC_OPS_H
+#if (defined(HAVE_ATOMIC_OPS_H) || defined(HAVE_ATOMIC_H)) \
+    && !defined(CONFIG_CACHE_WAIT)
     AO_TS_t busy;              /* is the rs-cache busy? */
 #else
     pthread_mutex_t lock;

diff --git a/src/dwarf/Gparser.c b/src/dwarf/Gparser.c
index 3969cb3..3a15344 100644
--- a/src/dwarf/Gparser.c
+++ b/src/dwarf/Gparser.c
@@ -481,20 +481,18 @@ get_rs_cache (unw_addr_space_t as, intrmask_t 
*saved_maskp)
   if (caching == UNW_CACHE_NONE)
     return NULL;
 
-#ifdef HAVE_ATOMIC_H
+#if defined(HAVE_ATOMIC_H) && !defined(CONFIG_CACHE_WAIT)
   if (!spin_trylock_irqsave (&cache->busy, *saved_maskp))
     return NULL;
-#else
-# ifdef HAVE_ATOMIC_OPS_H
+#elif defined(HAVE_ATOMIC_OPS_H) && !defined(CONFIG_CACHE_WAIT)
   if (AO_test_and_set (&cache->busy) == AO_TS_SET)
     return NULL;
-# else
+#else
   if (likely (caching == UNW_CACHE_GLOBAL))
     {
       Debug (16, "%s: acquiring lock\n", __FUNCTION__);
       lock_acquire (&cache->lock, *saved_maskp);
     }
-# endif
 #endif
 
   if (atomic_read (&as->cache_generation) != atomic_read (&cache->generation))
@@ -513,15 +511,13 @@ put_rs_cache (unw_addr_space_t as, struct dwarf_rs_cache 
*cache,
   assert (as->caching_policy != UNW_CACHE_NONE);
 
   Debug (16, "unmasking signals/interrupts and releasing lock\n");
-#ifdef HAVE_ATOMIC_H
+#if defined(HAVE_ATOMIC_H) && !defined(CONFIG_CACHE_WAIT)
   spin_unlock_irqrestore (&cache->busy, *saved_maskp);
-#else
-# ifdef HAVE_ATOMIC_OPS_H
+#elif defined(HAVE_ATOMIC_OPS_H) && !defined(CONFIG_CACHE_WAIT)
   AO_CLEAR (&cache->busy);
-# else
+#else
   if (likely (as->caching_policy == UNW_CACHE_GLOBAL))
     lock_release (&cache->lock, *saved_maskp);
-# endif
 #endif
 }
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]