[Top][All Lists]
[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
}
- [Libunwind-devel] [patch] Allow for complete stack traces even when other threads iterfere.,
Paul Pluzhnikov <=