[PATCH] D18121: [sanitizer] On OS X, verify that interceptors work and abort if not

Kuba Brecka via llvm-commits llvm-commits at lists.llvm.org
Sat Mar 12 10:53:47 PST 2016


kubabrecka created this revision.
kubabrecka added reviewers: samsonov, kcc, glider, dvyukov.
kubabrecka added subscribers: llvm-commits, zaks.anna.

On OS X 10.11+, we have "automatic interceptors", so we don't need to use DYLD_INSERT_LIBRARIES when launching instrumented programs.  However, non-instrumented programs that load TSan late (e.g. via dlopen) are currently broken, as TSan will still try to initialize, but the program will crash/hang at random places (because the interceptors don't work).  This patch adds an explicit check that interceptors are working, and if not, it aborts and prints out an error message suggesting to explicitly use DYLD_INSERT_LIBRARIES.

http://reviews.llvm.org/D18121

Files:
  lib/sanitizer_common/sanitizer_mac.cc
  test/tsan/Darwin/dlopen.cc

Index: test/tsan/Darwin/dlopen.cc
===================================================================
--- test/tsan/Darwin/dlopen.cc
+++ test/tsan/Darwin/dlopen.cc
@@ -0,0 +1,46 @@
+// Checks that on OS X 10.11+ (where we do not re-exec anymore, because
+// interceptors work automatically), dlopen'ing a TSanified library from a
+// non-instrumented program exits with a user-friendly message.
+
+// RUN: %clangxx_tsan %s -o %t-instr -DINSTRUMENTED_PART=1
+// RUN: %clangxx_tsan -fno-sanitize=thread %s -o %t-noninstr -DINSTRUMENTED_PART=0 -DINSTRUMENTED_PART_LIB_NAME="\"%t-instr\""
+
+// Launching a regular instrumented binary just works.  Either interceptors
+// already work or we re-exec.
+// RUN: %run %t-instr 2>&1 | FileCheck %s
+
+// RUN: IS_OSX_10_11_OR_HIGHER=$([ `sw_vers -productVersion | cut -d'.' -f2` -lt 11 ]; echo $?)
+// RUN: TSAN_DYLIB_PATH=`%clangxx_tsan %s -### 2>&1 \
+// RUN:   | grep "libclang_rt.tsan_osx_dynamic.dylib" \
+// RUN:   | sed -e 's/.*"\(.*libclang_rt.tsan_osx_dynamic.dylib\)".*/\1/'`
+
+// RUN: if [ $IS_OSX_10_11_OR_HIGHER == 1 ]; then \
+//        Launching a non-instrumented binary that dlopen's an instrumented library should fail.
+// RUN:   not %run %t-noninstr 2>&1 | FileCheck %s --check-prefix=CHECK-FAIL; \
+//        Launching a non-instrumented binary with an explicit DYLD_INSERT_LIBRARIES should work.
+// RUN:   DYLD_INSERT_LIBRARIES=$TSAN_DYLIB_PATH %run %t-noninstr 2>&1 | FileCheck %s; \
+// RUN: fi
+
+#include <dlfcn.h>
+#include <pthread.h>
+#include <stdio.h>
+
+#if INSTRUMENTED_PART == 1
+int main() {
+  fprintf(stderr, "Hello world.\n");
+}
+#else // INSTRUMENTED_PART == 1
+int main() {
+  void *handle = dlopen(INSTRUMENTED_PART_LIB_NAME, RTLD_NOW);
+  fprintf(stderr, "handle = %p\n", handle);
+  int (*other_main)() = (int (*)())dlsym(handle, "main");
+  fprintf(stderr, "other_main = %p\n", other_main);
+  other_main();
+}
+#endif
+
+// CHECK: Hello world.
+// CHECK-NOT: ERROR: Interceptors are not working.
+
+// CHECK-FAIL-NOT: Hello world.
+// CHECK-FAIL: ERROR: Interceptors are not working.
Index: lib/sanitizer_common/sanitizer_mac.cc
===================================================================
--- lib/sanitizer_common/sanitizer_mac.cc
+++ lib/sanitizer_common/sanitizer_mac.cc
@@ -627,6 +627,21 @@
     CHECK("execv failed" && 0);
   }
 
+  // Verify that interceptors really work.  We'll use dlsym to locate
+  // "pthread_create", if interceptors are working, it should really point to
+  // "wrap_pthread_create" within our own dylib.
+  Dl_info info_pthread_create;
+  void *dlopen_addr = dlsym(RTLD_DEFAULT, "pthread_create");
+  CHECK(dladdr(dlopen_addr, &info_pthread_create));
+  if (internal_strcmp(info.dli_fname, info_pthread_create.dli_fname) != 0) {
+    Report(
+        "ERROR: Interceptors are not working. This may be because %s is "
+        "loaded too late (e.g. via dlopen). Please launch the executable "
+        "with:\n%s=%s\n",
+        SanitizerToolName, kDyldInsertLibraries, info.dli_fname);
+    CHECK("interceptors not installed" && 0);
+  }
+
   if (!lib_is_in_env)
     return;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D18121.50527.patch
Type: text/x-patch
Size: 3105 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160312/3115432c/attachment.bin>


More information about the llvm-commits mailing list