[OpenMP][Tool] Runtime warning for missing TSan-option
authorJoachim Protze <protze@itc.rwth-aachen.de>
Tue, 14 Jan 2020 08:24:00 +0000 (22:24 -1000)
committerJoachim Protze <protze@itc.rwth-aachen.de>
Tue, 14 Jan 2020 19:58:05 +0000 (09:58 -1000)
TSan spuriously reports for any OpenMP application a race on the initialization
of a runtime internal mutex:

```
Atomic read of size 1 at 0x7b6800005940 by thread T4:
  #0 pthread_mutex_lock <null> (a.out+0x43f39e)
  #1 __kmp_resume_64 <null> (libomp.so.5+0x84db4)

Previous write of size 1 at 0x7b6800005940 by thread T7:
  #0 pthread_mutex_init <null> (a.out+0x424793)
  #1 __kmp_suspend_initialize_thread <null> (libomp.so.5+0x8422e)
```

According to @AndreyChurbanov this is a false positive report, as the control
flow of the runtime guarantees the ordering of the mutex initialization and
the lock:
https://software.intel.com/en-us/forums/intel-open-source-openmp-runtime-library/topic/530363

To suppress this report, I suggest the use of
TSAN_OPTIONS='ignore_uninstrumented_modules=1'.
With this patch, a runtime warning is provided in case an OpenMP application
is built with Tsan and executed without this Tsan-option.

Reviewed By: jdoerfert

Differential Revision: https://reviews.llvm.org/D70412

openmp/CREDITS.txt
openmp/tools/archer/ompt-tsan.cpp

index b14bb9a1e6e60bba96892c93eb122f88b675042d..ede45b10fea2524845e5dc1a259573fb27207dcf 100644 (file)
@@ -53,6 +53,10 @@ N: Steven Noonan
 E: steven@uplinklabs.net
 D: Patches for the ARM architecture and removal of several inconsistencies.
 
+N: Joachim Protze
+E: protze@itc.rwth-aachen.de
+D: OpenMP Tools Interface, Archer tool
+
 N: Alp Toker
 E: alp@nuanti.com
 D: Making build work for FreeBSD.
index 03a2f6c148fe3957e9093c05fea47d859836999f..50b98e2a4851960ef6020ebd3f98de9927c66549 100644 (file)
@@ -82,6 +82,31 @@ public:
   }
 };
 
+class TsanFlags {
+public:
+  int ignore_noninstrumented_modules;
+
+  TsanFlags(const char *env) : ignore_noninstrumented_modules(0) {
+    if (env) {
+      std::vector<std::string> tokens;
+      std::string token;
+      std::string str(env);
+      std::istringstream iss(str);
+      while (std::getline(iss, token, ' '))
+        tokens.push_back(token);
+
+      for (std::vector<std::string>::iterator it = tokens.begin();
+           it != tokens.end(); ++it) {
+        // we are interested in ignore_noninstrumented_modules to print a
+        // warning
+        if (sscanf(it->c_str(), "ignore_noninstrumented_modules=%d",
+                   &ignore_noninstrumented_modules))
+          continue;
+      }
+    }
+  }
+};
+
 #if (LLVM_VERSION) >= 40
 extern "C" {
 int __attribute__((weak)) __archer_get_omp_status();
@@ -89,6 +114,7 @@ void __attribute__((weak)) __tsan_flush_memory() {}
 }
 #endif
 ArcherFlags *archer_flags;
+TsanFlags *tsan_flags;
 
 // The following definitions are pasted from "llvm/Support/Compiler.h" to allow
 // the code
@@ -838,6 +864,8 @@ static int ompt_tsan_initialize(ompt_function_lookup_t lookup,
                                 ompt_data_t *tool_data) {
   const char *options = getenv("ARCHER_OPTIONS");
   archer_flags = new ArcherFlags(options);
+  options = getenv("TSAN_OPTIONS");
+  tsan_flags = new TsanFlags(options);
 
   ompt_set_callback_t ompt_set_callback =
       (ompt_set_callback_t)lookup("ompt_set_callback");
@@ -869,6 +897,12 @@ static int ompt_tsan_initialize(ompt_function_lookup_t lookup,
   SET_CALLBACK_T(mutex_acquired, mutex);
   SET_CALLBACK_T(mutex_released, mutex);
   SET_OPTIONAL_CALLBACK_T(reduction, sync_region, hasReductionCallback, ompt_set_never);
+
+  if (!tsan_flags->ignore_noninstrumented_modules)
+    fprintf(
+        stderr,
+        "Warning: please export TSAN_OPTIONS='ignore_noninstrumented_modules=1' "
+        "to avoid false positive reports from the OpenMP runtime.!\n");
   return 1; // success
 }