Work around a few missing msan interceptors
Change-Id: Ia8ab95b41e67b915a9426d0b7567f66e3f0190ae
diff --git a/aos/ipc_lib/signalfd.cc b/aos/ipc_lib/signalfd.cc
index 363bf4a..051a654 100644
--- a/aos/ipc_lib/signalfd.cc
+++ b/aos/ipc_lib/signalfd.cc
@@ -2,6 +2,9 @@
#include <signal.h>
#include <sys/types.h>
+#if __has_feature(memory_sanitizer)
+#include <sanitizer/msan_interface.h>
+#endif
#include <unistd.h>
#include <initializer_list>
@@ -9,6 +12,50 @@
namespace aos {
namespace ipc_lib {
+namespace {
+
+// Wrapper which propagates msan information.
+// TODO(Brian): Drop this once we have <https://reviews.llvm.org/D82411> to
+// intercept this function natively.
+int wrapped_sigandset(sigset_t *dest, const sigset_t *left,
+ const sigset_t *right) {
+#if __has_feature(memory_sanitizer)
+ if (left) {
+ __msan_check_mem_is_initialized(left, sizeof(*left));
+ }
+ if (right) {
+ __msan_check_mem_is_initialized(right, sizeof(*right));
+ }
+#endif
+ const int r = sigandset(dest, left, right);
+#if __has_feature(memory_sanitizer)
+ if (!r && dest) {
+ __msan_unpoison(dest, sizeof(*dest));
+ }
+#endif
+ return r;
+}
+
+// Wrapper which propagates msan information.
+// TODO(Brian): Drop this once we have
+// <https://reviews.llvm.org/rG89ae290b58e20fc5f56b7bfae4b34e7fef06e1b1> to
+// intercept this function natively.
+int wrapped_pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset) {
+#if __has_feature(memory_sanitizer)
+ if (set) {
+ __msan_check_mem_is_initialized(set, sizeof(*set));
+ }
+#endif
+ const int r = pthread_sigmask(how, set, oldset);
+#if __has_feature(memory_sanitizer)
+ if (!r && oldset) {
+ __msan_unpoison(oldset, sizeof(*oldset));
+ }
+#endif
+ return r;
+}
+
+} // namespace
SignalFd::SignalFd(::std::initializer_list<unsigned int> signals) {
// Build up the mask with the provided signals.
@@ -23,7 +70,7 @@
// signalfd gets them. Record which ones we actually blocked, so we can
// unblock just those later.
sigset_t old_mask;
- CHECK_EQ(0, pthread_sigmask(SIG_BLOCK, &blocked_mask_, &old_mask));
+ CHECK_EQ(0, wrapped_pthread_sigmask(SIG_BLOCK, &blocked_mask_, &old_mask));
for (int signal : signals) {
if (sigismember(&old_mask, signal)) {
CHECK_EQ(0, sigdelset(&blocked_mask_, signal));
@@ -35,9 +82,9 @@
// Unwind the constructor. Unblock the signals and close the fd. Verify nobody
// else unblocked the signals we're supposed to unblock in the meantime.
sigset_t old_mask;
- CHECK_EQ(0, pthread_sigmask(SIG_UNBLOCK, &blocked_mask_, &old_mask));
+ CHECK_EQ(0, wrapped_pthread_sigmask(SIG_UNBLOCK, &blocked_mask_, &old_mask));
sigset_t unblocked_mask;
- CHECK_EQ(0, sigandset(&unblocked_mask, &blocked_mask_, &old_mask));
+ CHECK_EQ(0, wrapped_sigandset(&unblocked_mask, &blocked_mask_, &old_mask));
if (memcmp(&unblocked_mask, &blocked_mask_, sizeof(unblocked_mask)) != 0) {
LOG(FATAL) << "Some other code unblocked one or more of our signals";
}
diff --git a/aos/logging/context.cc b/aos/logging/context.cc
index 72c1970..84e4e80 100644
--- a/aos/logging/context.cc
+++ b/aos/logging/context.cc
@@ -4,6 +4,9 @@
#define _GNU_SOURCE /* See feature_test_macros(7) */
#endif
+#if __has_feature(memory_sanitizer)
+#include <sanitizer/msan_interface.h>
+#endif
#include <string.h>
#include <sys/prctl.h>
#include <sys/types.h>
@@ -16,8 +19,8 @@
extern char *program_invocation_name;
extern char *program_invocation_short_name;
-#include "aos/die.h"
#include "aos/complex_thread_local.h"
+#include "aos/die.h"
namespace aos {
namespace logging {
@@ -39,6 +42,10 @@
if (prctl(PR_GET_NAME, thread_name_array) != 0) {
PDie("prctl(PR_GET_NAME, %p) failed", thread_name_array);
}
+#if __has_feature(memory_sanitizer)
+ // msan doesn't understand PR_GET_NAME, so help it along.
+ __msan_unpoison(thread_name_array, sizeof(thread_name_array));
+#endif
thread_name_array[sizeof(thread_name_array) - 1] = '\0';
::std::string thread_name(thread_name_array);
@@ -67,8 +74,7 @@
::std::atomic<LogImplementation *> global_top_implementation(NULL);
Context::Context()
- : implementation(global_top_implementation.load()),
- sequence(0) {
+ : implementation(global_top_implementation.load()), sequence(0) {
cork_data.Reset();
}
@@ -77,8 +83,7 @@
if (my_context.created()) {
::std::string my_name = GetMyName();
if (my_name.size() + 1 > sizeof(Context::name)) {
- Die("logging: process/thread name '%s' is too long\n",
- my_name.c_str());
+ Die("logging: process/thread name '%s' is too long\n", my_name.c_str());
}
strcpy(my_context->name, my_name.c_str());
my_context->name_size = my_name.size();
@@ -98,9 +103,7 @@
return my_context.get();
}
-void Context::Delete() {
- delete_current_context = true;
-}
+void Context::Delete() { delete_current_context = true; }
} // namespace internal
} // namespace logging