aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAliaksey Kandratsenka <alkondratenko@gmail.com>2016-04-09 13:09:18 -0700
committerAliaksey Kandratsenka <alkondratenko@gmail.com>2016-04-09 13:09:18 -0700
commit7852eeb75b9375cf52a7da01be044da6e915dd08 (patch)
tree86e2e5d4d04df796cff4f06898039bdc26418716
parenta07f9fe75af25ce388af3d4ff4514b42513d766f (diff)
downloadgperftools-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.h6
-rw-r--r--src/stacktrace_libunwind-inl.h4
-rw-r--r--src/thread_cache.h6
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;