From 6737c9f59a523a4813f6e825bfbf3db2dcb00432 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 15 Jun 2016 22:19:56 +0200 Subject: [PATCH] Use initial-exec tls for libunwind's recursion flag RH-Author: Paolo Bonzini Message-id: <1466029196-19454-1-git-send-email-pbonzini@redhat.com> Patchwork-id: 70630 O-Subject: [RHEL7.3 PATCH gperftools] Use initial-exec tls for libunwind's recursion flag Bugzilla: 1339710 RH-Acked-by: Miroslav Rezanina RH-Acked-by: Bandan Das RH-Acked-by: Laszlo Ersek From: Aliaksey Kandratsenka Bugzilla: 1339710 Brew build: 11181349 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. Signed-off-by: Paolo Bonzini (cherry picked from commit 7852eeb75b9375cf52a7da01be044da6e915dd08) Signed-off-by: Miroslav Rezanina --- src/base/basictypes.h | 6 ++++++ src/stacktrace_libunwind-inl.h | 4 +++- 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 4779611..d7c0f7a 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 } #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 5edcdfb..27109af 100644 --- a/src/thread_cache.h +++ b/src/thread_cache.h @@ -252,12 +252,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; -- 1.8.3.1