<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Apr 8, 2013 at 9:46 PM, Alexander Potapenko <span dir="ltr"><<a href="mailto:glider@google.com" target="_blank">glider@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: glider<br>
Date: Mon Apr  8 12:46:34 2013<br>
New Revision: 179032<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=179032&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=179032&view=rev</a><br>
Log:<br>
[libsymbolized] If we can't find an address in the list of shared libraries, try to reload it.<br>
<br>
Add a regression test for the case where such behavior helps TSan:<br>
  1. race is reported in the main module<br>
  2. new shared library is loaded<br>
  3. race is reported in the shared library<br>
<br>
<br>
Added:<br>
    compiler-rt/trunk/lib/tsan/lit_tests/SharedLibs/<br>
    compiler-rt/trunk/lib/tsan/lit_tests/SharedLibs/lit.local.cfg<br>
    compiler-rt/trunk/lib/tsan/lit_tests/SharedLibs/load_shared_lib-so.cc<br>
    compiler-rt/trunk/lib/tsan/lit_tests/load_shared_lib.cc<br>
Modified:<br>
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc?rev=179032&r1=179031&r2=179032&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc?rev=179032&r1=179031&r2=179032&view=diff</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.cc Mon Apr  8 12:46:34 2013<br>
@@ -239,6 +239,7 @@ class InternalSymbolizer {<br>
<br>
 class Symbolizer {<br>
  public:<br>
+  Symbolizer() : modules_fresh_(false) { };<br>
   uptr SymbolizeCode(uptr addr, AddressInfo *frames, uptr max_frames) {<br>
     if (max_frames == 0)<br>
       return 0;<br>
@@ -376,7 +377,8 @@ class Symbolizer {<br>
   }<br>
<br>
   LoadedModule *FindModuleForAddress(uptr address) {<br>
-    if (modules_ == 0) {<br>
+    bool modules_were_reloaded = false;<br>
+    if (modules_ == 0 || !modules_fresh_) {<br>
       modules_ = (LoadedModule*)(symbolizer_allocator.Allocate(<br>
           kMaxNumberOfModuleContexts * sizeof(LoadedModule)));<br></blockquote><div><br></div><div style>Do you allocate new array of modules each time address is not found (and leak the previous array)?</div><div style>
This is dangerous - sizeof(array of modules) is pretty large, and TSan may quickly leak memory in this case...</div><div style>I think we may switch to InternalVector<> for storing modules here, and call .clear() on it to unmap memory.</div>
<div style><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
       CHECK(modules_);<br>
@@ -384,14 +386,25 @@ class Symbolizer {<br>
       // FIXME: Return this check when GetListOfModules is implemented on Mac.<br>
       // CHECK_GT(n_modules_, 0);<br>
       CHECK_LT(n_modules_, kMaxNumberOfModuleContexts);<br>
+      modules_fresh_ = true;<br>
+      modules_were_reloaded = true;<br>
     }<br>
     for (uptr i = 0; i < n_modules_; i++) {<br>
       if (modules_[i].containsAddress(address)) {<br>
         return &modules_[i];<br>
       }<br>
     }<br>
+    // Reload the modules and look up again, if we haven't tried it yet.<br>
+    if (!modules_were_reloaded) {<br>
+      // FIXME: set modules_fresh_ from dlopen()/dlclose() interceptors.<br>
+      // It's too aggressive to reload the list of modules each time we fail<br>
+      // to find a module for a given address.<br>
+      modules_fresh_ = false;<br>
+      return FindModuleForAddress(address);<br>
+    }<br>
     return 0;<br>
   }<br>
+<br>
   void ReportExternalSymbolizerError(const char *msg) {<br>
     // Don't use atomics here for now, as SymbolizeCode can't be called<br>
     // from multiple threads anyway.<br>
@@ -406,6 +419,8 @@ class Symbolizer {<br>
   static const uptr kMaxNumberOfModuleContexts = 1 << 14;<br>
   LoadedModule *modules_;  // Array of module descriptions is leaked.<br>
   uptr n_modules_;<br>
+  // If stale, need to reload the modules before looking up addresses.<br>
+  bool modules_fresh_;<br>
<br>
   ExternalSymbolizer *external_symbolizer_;  // Leaked.<br>
   InternalSymbolizer *internal_symbolizer_;  // Leaked.<br>
<br>
Added: compiler-rt/trunk/lib/tsan/lit_tests/SharedLibs/lit.local.cfg<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/SharedLibs/lit.local.cfg?rev=179032&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/SharedLibs/lit.local.cfg?rev=179032&view=auto</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/lit_tests/SharedLibs/lit.local.cfg (added)<br>
+++ compiler-rt/trunk/lib/tsan/lit_tests/SharedLibs/lit.local.cfg Mon Apr  8 12:46:34 2013<br>
@@ -0,0 +1,4 @@<br>
+# Sources in this directory are compiled as shared libraries and used by<br>
+# tests in parent directory.<br>
+<br>
+config.suffixes = []<br>
<br>
Added: compiler-rt/trunk/lib/tsan/lit_tests/SharedLibs/load_shared_lib-so.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/SharedLibs/load_shared_lib-so.cc?rev=179032&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/SharedLibs/load_shared_lib-so.cc?rev=179032&view=auto</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/lit_tests/SharedLibs/load_shared_lib-so.cc (added)<br>
+++ compiler-rt/trunk/lib/tsan/lit_tests/SharedLibs/load_shared_lib-so.cc Mon Apr  8 12:46:34 2013<br>
@@ -0,0 +1,22 @@<br>
+//===----------- load_shared_lib-so.cc --------------------------*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file is a part of ThreadSanitizer (TSan), a race detector.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include <stddef.h><br>
+<br>
+int GLOB_SHARED = 0;<br>
+<br>
+extern "C"<br>
+void *write_from_so(void *unused) {<br>
+  GLOB_SHARED++;<br>
+  return NULL;<br>
+}<br>
<br>
Added: compiler-rt/trunk/lib/tsan/lit_tests/load_shared_lib.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/load_shared_lib.cc?rev=179032&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/load_shared_lib.cc?rev=179032&view=auto</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/lit_tests/load_shared_lib.cc (added)<br>
+++ compiler-rt/trunk/lib/tsan/lit_tests/load_shared_lib.cc Mon Apr  8 12:46:34 2013<br>
@@ -0,0 +1,44 @@<br>
+// Check that if the list of shared libraries changes between the two race<br>
+// reports, the second report occurring in a new shared library is still<br>
+// symbolized correctly.<br>
+<br>
+// RUN: %clangxx_tsan -O1 %p/SharedLibs/load_shared_lib-so.cc \<br>
+// RUN:     -fPIC -shared -o %t-so.so<br>
+// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s<br>
+<br>
+#include <dlfcn.h><br>
+#include <pthread.h><br>
+#include <stdio.h><br>
+<br>
+#include <string><br>
+<br>
+int GLOB = 0;<br>
+<br>
+void *write_glob(void *unused) {<br>
+  GLOB++;<br>
+  return NULL;<br>
+}<br>
+<br>
+void race_two_threads(void *(*access_callback)(void *)) {<br>
+  pthread_t t1, t2;<br>
+  pthread_create(&t1, NULL, access_callback, NULL);<br>
+  pthread_create(&t2, NULL, access_callback, NULL);<br>
+  pthread_join(t1, NULL);<br>
+  pthread_join(t2, NULL);<br>
+}<br>
+<br>
+int main(int argc, char *argv[]) {<br>
+  std::string path = std::string(argv[0]) + std::string("-so.so");<br>
+  race_two_threads(write_glob);<br>
+  // CHECK: write_glob<br>
+  void *lib = dlopen(path.c_str(), RTLD_NOW);<br>
+    if (!lib) {<br>
+    printf("error in dlopen(): %s\n", dlerror());<br>
+    return 1;<br>
+  }<br>
+  void *(*write_from_so)(void *);<br>
+  *(void **)&write_from_so = dlsym(lib, "write_from_so");<br>
+  race_two_threads(write_from_so);<br>
+  // CHECK: write_from_so<br>
+  return 0;<br>
+}<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div>Alexey Samsonov, MSK</div>
</div></div>