diff options
author | Aliaksey Kandratsenka <alkondratenko@gmail.com> | 2016-04-09 13:09:18 -0700 |
---|---|---|
committer | Aliaksey Kandratsenka <alkondratenko@gmail.com> | 2016-04-09 13:09:18 -0700 |
commit | 7852eeb75b9375cf52a7da01be044da6e915dd08 (patch) | |
tree | 86e2e5d4d04df796cff4f06898039bdc26418716 | |
parent | a07f9fe75af25ce388af3d4ff4514b42513d766f (diff) | |
download | gperftools-7852eeb75b9375cf52a7da01be044da6e915dd08.tar.gz |
Use initial-exec tls for libunwind's recursion flag
If we don't do it, then reading variable calls to __tls_get_addr, which
uses malloc on first call. initial-exec makes dynamic linker reserve tls
offset for recusion flag early and thus avoid unsafe calls to malloc.
This fixes issue #786.
-rw-r--r-- | src/base/basictypes.h | 6 | ||||
-rw-r--r-- | src/stacktrace_libunwind-inl.h | 4 | ||||
-rw-r--r-- | src/thread_cache.h | 6 |
3 files changed, 9 insertions, 7 deletions
diff --git a/src/base/basictypes.h b/src/base/basictypes.h index f0e25da..b628709 100644 --- a/src/base/basictypes.h +++ b/src/base/basictypes.h @@ -192,6 +192,12 @@ struct CompileAssert { # define ATTRIBUTE_UNUSED #endif +#if defined(HAVE___ATTRIBUTE__) && defined(HAVE_TLS) +#define ATTR_INITIAL_EXEC __attribute__ ((tls_model ("initial-exec"))) +#else +#define ATTR_INITIAL_EXEC +#endif + #define COMPILE_ASSERT(expr, msg) \ typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] ATTRIBUTE_UNUSED diff --git a/src/stacktrace_libunwind-inl.h b/src/stacktrace_libunwind-inl.h index 8a4a731..6f361ec 100644 --- a/src/stacktrace_libunwind-inl.h +++ b/src/stacktrace_libunwind-inl.h @@ -47,6 +47,8 @@ extern "C" { #include <libunwind.h> } #include "gperftools/stacktrace.h" + +#include "base/basictypes.h" #include "base/logging.h" // Sometimes, we can try to get a stack trace from within a stack @@ -56,7 +58,7 @@ extern "C" { // recursive request, we'd end up with infinite recursion or deadlock. // Luckily, it's safe to ignore those subsequent traces. In such // cases, we return 0 to indicate the situation. -static __thread int recursive; +static __thread int recursive ATTR_INITIAL_EXEC; #if defined(TCMALLOC_ENABLE_UNWIND_FROM_UCONTEXT) && (defined(__i386__) || defined(__x86_64__)) && defined(__GNU_LIBRARY__) #define BASE_STACKTRACE_UNW_CONTEXT_IS_UCONTEXT 1 diff --git a/src/thread_cache.h b/src/thread_cache.h index 445a0b5..67f5761 100644 --- a/src/thread_cache.h +++ b/src/thread_cache.h @@ -259,12 +259,6 @@ class ThreadCache { // Since we don't really use dlopen in google code -- and using dlopen // on a malloc replacement is asking for trouble in any case -- that's // a good tradeoff for us. -#ifdef HAVE___ATTRIBUTE__ -#define ATTR_INITIAL_EXEC __attribute__ ((tls_model ("initial-exec"))) -#else -#define ATTR_INITIAL_EXEC -#endif - #ifdef HAVE_TLS struct ThreadLocalData { ThreadCache* heap; |