Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Sysv contexts: add Asan instrumentation.
authorArnaud Giersch <arnaud.giersch@univ-fcomte.fr>
Sat, 9 Jun 2018 20:37:09 +0000 (22:37 +0200)
committerArnaud Giersch <arnaud.giersch@univ-fcomte.fr>
Sun, 10 Jun 2018 17:02:25 +0000 (19:02 +0200)
CMakeLists.txt
src/kernel/context/ContextUnix.cpp
src/kernel/context/ContextUnix.hpp

index 80ff66e..c7a9f3b 100644 (file)
@@ -507,8 +507,6 @@ if(NOT HAVE_UCONTEXT_H)
 elseif(APPLE)
   message(STATUS "No ucontext factory: Apple don't want us to use them.")
   set(HAVE_UCONTEXT_H 0)
-elseif(enable_address_sanitizer)
-  message(STATUS "No ucontext factory: ASan needs us to write the wrappers as explained in https://github.com/google/sanitizers/issues/189")
 else()
   try_compile(compile_makecontext ${CMAKE_BINARY_DIR} ${CMAKE_HOME_DIRECTORY}/tools/cmake/test_prog/prog_makecontext.c
     OUTPUT_VARIABLE compile_makecontext_output)
index dcb9088..4c509ba 100644 (file)
@@ -6,6 +6,7 @@
 /* \file UContext.cpp Context switching with ucontexts from System V        */
 
 #include "ContextUnix.hpp"
+#include "context_private.hpp"
 
 #include "mc/mc.h"
 #include "src/mc/mc_ignore.hpp"
@@ -85,6 +86,11 @@ UContext::UContext(std::function<void()> code, void_pfn_smxprocess_t cleanup_fun
     this->uc_.uc_link = nullptr;
     this->uc_.uc_stack.ss_sp   = sg_makecontext_stack_addr(this->stack_);
     this->uc_.uc_stack.ss_size = sg_makecontext_stack_size(smx_context_usable_stack_size);
+#if PTH_STACKGROWTH == -1
+    ASAN_EVAL(this->asan_stack_ = static_cast<char*>(this->stack_) + smx_context_usable_stack_size);
+#else
+    ASAN_EVAL(this->asan_stack_ = this->stack_);
+#endif
     UContext::make_ctx(&this->uc_, UContext::smx_ctx_sysv_wrapper, this);
   } else {
     if (process != nullptr && maestro_context_ == nullptr)
@@ -112,12 +118,14 @@ void UContext::smx_ctx_sysv_wrapper(int i1, int i2)
   simgrid::kernel::context::UContext* context;
   memcpy(&context, ctx_addr, sizeof context);
 
+  ASAN_FINISH_SWITCH(nullptr, &context->asan_ctx_->asan_stack_, &context->asan_ctx_->asan_stack_size_);
   try {
     (*context)();
     context->Context::stop();
   } catch (simgrid::kernel::context::Context::StopRequest const&) {
     XBT_DEBUG("Caught a StopRequest");
   }
+  ASAN_EVAL(context->asan_stop_ = true);
   context->suspend();
 }
 
@@ -133,6 +141,15 @@ void UContext::make_ctx(ucontext_t* ucp, void (*func)(int, int), UContext* arg)
   makecontext(ucp, (void (*)())func, 2, ctx_addr[0], ctx_addr[1]);
 }
 
+inline void UContext::swap(UContext* from, UContext* to)
+{
+  void* fake_stack = nullptr;
+  ASAN_EVAL(to->asan_ctx_ = from);
+  ASAN_START_SWITCH(from->asan_stop_ ? nullptr : &fake_stack, to->asan_stack_, to->asan_stack_size_);
+  swapcontext(&from->uc_, &to->uc_);
+  ASAN_FINISH_SWITCH(fake_stack, &from->asan_ctx_->asan_stack_, &from->asan_ctx_->asan_stack_size_);
+}
+
 void UContext::stop()
 {
   Context::stop();
index 8bc8ce6..2ee74ad 100644 (file)
@@ -32,7 +32,7 @@ public:
   void stop() override;
   virtual void resume() = 0;
 
-  static void swap(UContext* from, UContext* to) { swapcontext(&from->uc_, &to->uc_); }
+  static void swap(UContext* from, UContext* to);
   static UContext* getMaestro() { return maestro_context_; }
   static void setMaestro(UContext* maestro) { maestro_context_ = maestro; }
 
@@ -41,6 +41,13 @@ private:
   void* stack_ = nullptr; /* the thread stack */
   ucontext_t uc_;         /* the ucontext that executes the code */
 
+#if HAVE_SANITIZE_ADDRESS_FIBER_SUPPORT
+  const void* asan_stack_ = nullptr;
+  size_t asan_stack_size_ = 0;
+  UContext* asan_ctx_     = nullptr;
+  bool asan_stop_         = false;
+#endif
+
   static void smx_ctx_sysv_wrapper(int, int);
   static void make_ctx(ucontext_t* ucp, void (*func)(int, int), UContext* arg);
 };