Commit 58a6cebe authored by Dan Melnic's avatar Dan Melnic Committed by Facebook Github Bot

TSAN: AtForkList::child() - ignore reads, writes and sync

Summary:
TSAN: AtForkList::child() - ignore reads, writes and sync

(Note: this ignores all push blocking failures!)

Reviewed By: yfeldblum

Differential Revision: D16196384

fbshipit-source-id: 28ea3b9fdb317eaffcb428f6ae705d5c4e5de887
parent b0e08c4a
...@@ -19,8 +19,10 @@ ...@@ -19,8 +19,10 @@
#include <list> #include <list>
#include <mutex> #include <mutex>
#include <folly/ScopeGuard.h>
#include <folly/lang/Exception.h> #include <folly/lang/Exception.h>
#include <folly/portability/PThread.h> #include <folly/portability/PThread.h>
#include <folly/synchronization/SanitizeThread.h>
namespace folly { namespace folly {
...@@ -70,6 +72,20 @@ class AtForkList { ...@@ -70,6 +72,20 @@ class AtForkList {
} }
static void child() noexcept { static void child() noexcept {
// if we fork a multithreaded process
// some of the TSAN mutexes might be locked
// so we just enable ignores for everything
// while handling the child callbacks
// This might still be an issue if we do not exec right away
annotate_ignore_reads_begin(__FILE__, __LINE__);
annotate_ignore_writes_begin(__FILE__, __LINE__);
annotate_ignore_sync_begin(__FILE__, __LINE__);
auto reenableAnnotationsGuard = folly::makeGuard([] {
annotate_ignore_reads_end(__FILE__, __LINE__);
annotate_ignore_writes_end(__FILE__, __LINE__);
annotate_ignore_sync_end(__FILE__, __LINE__);
});
auto& tasks = instance().tasks; auto& tasks = instance().tasks;
for (auto& task : tasks) { for (auto& task : tasks) {
task.child(); task.child();
......
...@@ -42,6 +42,18 @@ extern "C" FOLLY_ATTR_WEAK void AnnotateBenignRaceSized( ...@@ -42,6 +42,18 @@ extern "C" FOLLY_ATTR_WEAK void AnnotateBenignRaceSized(
long size, long size,
const char* desc); const char* desc);
extern "C" FOLLY_ATTR_WEAK void AnnotateIgnoreReadsBegin(const char* f, int l);
extern "C" FOLLY_ATTR_WEAK void AnnotateIgnoreReadsEnd(const char* f, int l);
extern "C" FOLLY_ATTR_WEAK void AnnotateIgnoreWritesBegin(const char* f, int l);
extern "C" FOLLY_ATTR_WEAK void AnnotateIgnoreWritesEnd(const char* f, int l);
extern "C" FOLLY_ATTR_WEAK void AnnotateIgnoreSyncBegin(const char* f, int l);
extern "C" FOLLY_ATTR_WEAK void AnnotateIgnoreSyncEnd(const char* f, int l);
#if _MSC_VER #if _MSC_VER
#define FOLLY_SANITIZE_THREAD_CALL_HOOK(name, ...) [](...) {}(__VA_ARGS__) #define FOLLY_SANITIZE_THREAD_CALL_HOOK(name, ...) [](...) {}(__VA_ARGS__)
#else #else
...@@ -122,5 +134,41 @@ void annotate_benign_race_sized_impl( ...@@ -122,5 +134,41 @@ void annotate_benign_race_sized_impl(
AnnotateBenignRaceSized, f, l, addr, size, desc); AnnotateBenignRaceSized, f, l, addr, size, desc);
} }
} }
void annotate_ignore_reads_begin_impl(const char* f, int l) {
if (kIsSanitizeThread) {
FOLLY_SANITIZE_THREAD_CALL_HOOK(AnnotateIgnoreReadsBegin, f, l);
}
}
void annotate_ignore_reads_end_impl(const char* f, int l) {
if (kIsSanitizeThread) {
FOLLY_SANITIZE_THREAD_CALL_HOOK(AnnotateIgnoreReadsEnd, f, l);
}
}
void annotate_ignore_writes_begin_impl(const char* f, int l) {
if (kIsSanitizeThread) {
FOLLY_SANITIZE_THREAD_CALL_HOOK(AnnotateIgnoreWritesBegin, f, l);
}
}
void annotate_ignore_writes_end_impl(const char* f, int l) {
if (kIsSanitizeThread) {
FOLLY_SANITIZE_THREAD_CALL_HOOK(AnnotateIgnoreWritesEnd, f, l);
}
}
void annotate_ignore_sync_begin_impl(const char* f, int l) {
if (kIsSanitizeThread) {
FOLLY_SANITIZE_THREAD_CALL_HOOK(AnnotateIgnoreSyncBegin, f, l);
}
}
void annotate_ignore_sync_end_impl(const char* f, int l) {
if (kIsSanitizeThread) {
FOLLY_SANITIZE_THREAD_CALL_HOOK(AnnotateIgnoreSyncEnd, f, l);
}
}
} // namespace detail } // namespace detail
} // namespace folly } // namespace folly
...@@ -61,6 +61,18 @@ void annotate_benign_race_sized_impl( ...@@ -61,6 +61,18 @@ void annotate_benign_race_sized_impl(
const char* f, const char* f,
int l); int l);
void annotate_ignore_reads_begin_impl(const char* f, int l);
void annotate_ignore_reads_end_impl(const char* f, int l);
void annotate_ignore_writes_begin_impl(const char* f, int l);
void annotate_ignore_writes_end_impl(const char* f, int l);
void annotate_ignore_sync_begin_impl(const char* f, int l);
void annotate_ignore_sync_end_impl(const char* f, int l);
} // namespace detail } // namespace detail
FOLLY_ALWAYS_INLINE static void annotate_rwlock_create( FOLLY_ALWAYS_INLINE static void annotate_rwlock_create(
...@@ -132,4 +144,49 @@ FOLLY_ALWAYS_INLINE static void annotate_benign_race_sized( ...@@ -132,4 +144,49 @@ FOLLY_ALWAYS_INLINE static void annotate_benign_race_sized(
} }
} }
FOLLY_ALWAYS_INLINE static void annotate_ignore_reads_begin(
const char* f,
int l) {
if (kIsSanitizeThread) {
detail::annotate_ignore_reads_begin_impl(f, l);
}
}
FOLLY_ALWAYS_INLINE static void annotate_ignore_reads_end(
const char* f,
int l) {
if (kIsSanitizeThread) {
detail::annotate_ignore_reads_end_impl(f, l);
}
}
FOLLY_ALWAYS_INLINE static void annotate_ignore_writes_begin(
const char* f,
int l) {
if (kIsSanitizeThread) {
detail::annotate_ignore_writes_begin_impl(f, l);
}
}
FOLLY_ALWAYS_INLINE static void annotate_ignore_writes_end(
const char* f,
int l) {
if (kIsSanitizeThread) {
detail::annotate_ignore_writes_end_impl(f, l);
}
}
FOLLY_ALWAYS_INLINE static void annotate_ignore_sync_begin(
const char* f,
int l) {
if (kIsSanitizeThread) {
detail::annotate_ignore_sync_begin_impl(f, l);
}
}
FOLLY_ALWAYS_INLINE static void annotate_ignore_sync_end(const char* f, int l) {
if (kIsSanitizeThread) {
detail::annotate_ignore_sync_end_impl(f, l);
}
}
} // namespace folly } // namespace folly
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment