Squashed 'third_party/marl/' changes from 14549e9d1..e007bd3dd
e007bd3dd Reland "Unpoison thread_local variables for MSAN (#228)"
git-subtree-dir: third_party/marl
git-subtree-split: e007bd3dd1b2e0eab1ace6048eace7c901f33c7b
Change-Id: I37225d84404ec01cf54b717b0a7c06aa76934650
diff --git a/include/marl/sanitizers.h b/include/marl/sanitizers.h
index aea997e..6993066 100644
--- a/include/marl/sanitizers.h
+++ b/include/marl/sanitizers.h
@@ -78,13 +78,14 @@
#define THREAD_SANITIZER_ONLY(x)
#endif // THREAD_SANITIZER_ENABLED
-// The CLANG_NO_SANITIZE_MEMORY macro suppresses MemorySanitizer checks for
-// use-of-uninitialized-data. It can be used to decorate functions with known
-// false positives.
-#ifdef __clang__
-#define CLANG_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory))
+// The MSAN_UNPOISON macro marks uninitialized memory as initialized for MSAN.
+// It can be used to suppress false-positive MSAN errors before reading
+// thread-local variables. See https://github.com/google/sanitizers/issues/1265
+#if MEMORY_SANITIZER_ENABLED
+#include <sanitizer/msan_interface.h>
+#define MSAN_UNPOISON(p, size) __msan_unpoison(p, size)
#else
-#define CLANG_NO_SANITIZE_MEMORY
+#define MSAN_UNPOISON(p, size)
#endif
#endif // marl_sanitizers_h
diff --git a/include/marl/scheduler.h b/include/marl/scheduler.h
index b402155..48acf02 100644
--- a/include/marl/scheduler.h
+++ b/include/marl/scheduler.h
@@ -21,6 +21,7 @@
#include "export.h"
#include "memory.h"
#include "mutex.h"
+#include "sanitizers.h"
#include "task.h"
#include "thread.h"
@@ -573,6 +574,7 @@
}
Scheduler::Worker* Scheduler::Worker::getCurrent() {
+ MSAN_UNPOISON(¤t, sizeof(Worker*));
return Worker::current;
}
diff --git a/src/scheduler.cpp b/src/scheduler.cpp
index c9ae3ee..43c2c1c 100644
--- a/src/scheduler.cpp
+++ b/src/scheduler.cpp
@@ -17,7 +17,6 @@
#include "marl/scheduler.h"
#include "marl/debug.h"
-#include "marl/sanitizers.h"
#include "marl/thread.h"
#include "marl/trace.h"
@@ -87,24 +86,17 @@
////////////////////////////////////////////////////////////////////////////////
thread_local Scheduler* Scheduler::bound = nullptr;
-CLANG_NO_SANITIZE_MEMORY
Scheduler* Scheduler::get() {
+ MSAN_UNPOISON(&bound, sizeof(Scheduler*));
return bound;
}
-CLANG_NO_SANITIZE_MEMORY
void Scheduler::setBound(Scheduler* scheduler) {
bound = scheduler;
}
void Scheduler::bind() {
-#if !MEMORY_SANITIZER_ENABLED
- // thread_local variables in shared libraries are initialized at load-time,
- // but this is not observed by MemorySanitizer if the loader itself was not
- // instrumented, leading to false-positive unitialized variable errors.
- // See https://github.com/google/marl/issues/184
MARL_ASSERT(get() == nullptr, "Scheduler already bound");
-#endif
setBound(this);
{
marl::lock lock(singleThreadedWorkers.mutex);
@@ -240,9 +232,6 @@
MARL_ASSERT(worker != nullptr, "No Scheduler::Worker bound");
}
-// TODO(chromium:1211047): Testing the static thread_local Worker::current for
-// null causes a MemorySantizer false positive.
-CLANG_NO_SANITIZE_MEMORY
Scheduler::Fiber* Scheduler::Fiber::current() {
auto worker = Worker::getCurrent();
return worker != nullptr ? worker->getCurrentFiber() : nullptr;