<p dir="ltr">Yes, if those are from JITted code.<br>
If that becomes a hot point, we'll need to intercept dlopen/dlclose instead.</p>
<div class="gmail_quote">On Apr 9, 2013 12:34 AM, "Dmitry Vyukov" <<a href="mailto:dvyukov@google.com">dvyukov@google.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
On Mon, Apr 8, 2013 at 10:46 AM, Alexander Potapenko <<a href="mailto:glider@google.com">glider@google.com</a>> wrote:<br>
> 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>
>        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>
Is it true that we do not find the module iff the maps are stale?<br>
I am thinking about the case when we symbolize 500 stack frames, and<br>
we can't find the module for some reason each time. Can it happen?<br>
<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>