diff options
author | Kostya Kortchinsky <kostyak@google.com> | 2020-01-09 11:43:16 -0800 |
---|---|---|
committer | Kostya Kortchinsky <kostyak@google.com> | 2020-01-14 07:51:48 -0800 |
commit | 9ef6faf49670e18eb1ba04105a7c70b450cdaa71 (patch) | |
tree | 30a9fbd7992361e720f7c0ae42f6b49e360a7813 /compiler-rt/lib/scudo/standalone/tsd_exclusive.h | |
parent | e7b2d9f4702cb8882aa275bcb8eab37be17601e1 (diff) | |
download | bcm5719-llvm-9ef6faf49670e18eb1ba04105a7c70b450cdaa71.tar.gz bcm5719-llvm-9ef6faf49670e18eb1ba04105a7c70b450cdaa71.zip |
[scudo][standalone] Fork support
Summary:
fork() wasn't well (or at all) supported in Scudo. This materialized
in deadlocks in children.
In order to properly support fork, we will lock the allocator pre-fork
and unlock it post-fork in parent and child. This is done via a
`pthread_atfork` call installing the necessary handlers.
A couple of things suck here: this function allocates - so this has to
be done post initialization as our init path is not reentrance, and it
doesn't allow for an extra pointer - so we can't pass the allocator we
are currently working with.
In order to work around this, I added a post-init template parameter
that gets executed once the allocator is initialized for the current
thread. Its job for the C wrappers is to install the atfork handlers.
I reorganized a bit the impacted area and added some tests, courtesy
of cferris@ that were deadlocking prior to this fix.
Subscribers: jfb, #sanitizers, llvm-commits
Tags: #sanitizers, #llvm
Differential Revision: https://reviews.llvm.org/D72470
Diffstat (limited to 'compiler-rt/lib/scudo/standalone/tsd_exclusive.h')
-rw-r--r-- | compiler-rt/lib/scudo/standalone/tsd_exclusive.h | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/compiler-rt/lib/scudo/standalone/tsd_exclusive.h b/compiler-rt/lib/scudo/standalone/tsd_exclusive.h index 89b001a739c..69479ea7bdf 100644 --- a/compiler-rt/lib/scudo/standalone/tsd_exclusive.h +++ b/compiler-rt/lib/scudo/standalone/tsd_exclusive.h @@ -11,8 +11,6 @@ #include "tsd.h" -#include <pthread.h> - namespace scudo { enum class ThreadState : u8 { @@ -62,6 +60,7 @@ template <class Allocator> struct TSDRegistryExT { // To disable the exclusive TSD registry, we effectively lock the fallback TSD // and force all threads to attempt to use it instead of their local one. void disable() { + Mutex.lock(); FallbackTSD->lock(); atomic_store(&Disabled, 1U, memory_order_release); } @@ -69,6 +68,7 @@ template <class Allocator> struct TSDRegistryExT { void enable() { atomic_store(&Disabled, 0U, memory_order_release); FallbackTSD->unlock(); + Mutex.unlock(); } private: @@ -90,6 +90,7 @@ private: pthread_setspecific(PThreadKey, reinterpret_cast<void *>(Instance)), 0); ThreadTSD.initLinkerInitialized(Instance); State = ThreadState::Initialized; + Instance->callPostInitCallback(); } pthread_key_t PThreadKey; |