<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>