diff options
author | Dmitry Vyukov <dvyukov@google.com> | 2016-11-22 09:49:11 +0000 |
---|---|---|
committer | Dmitry Vyukov <dvyukov@google.com> | 2016-11-22 09:49:11 +0000 |
commit | 48015d4e1a1d15e38e39516815fd6f9a80dc81b3 (patch) | |
tree | c6ff0d6d8b4b96d2dd936bf1ca225ec6cbb73166 /lib/sanitizer_common/sanitizer_libignore.cc | |
parent | f86bd316cab5a4947a8cc01a14b885503ca60de7 (diff) |
tsan: switch libignore from /proc/self/maps to dl_iterate_phdr
/proc/self/maps can't be read atomically, this leads to episodic
crashes in libignore as it thinks that a module is loaded twice.
See the new test for an example.
dl_iterate_phdr does not have this problem.
Switch libignore to dl_iterate_phdr.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@287632 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common/sanitizer_libignore.cc')
-rw-r--r-- | lib/sanitizer_common/sanitizer_libignore.cc | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/lib/sanitizer_common/sanitizer_libignore.cc b/lib/sanitizer_common/sanitizer_libignore.cc index 545393966..33a1763d2 100644 --- a/lib/sanitizer_common/sanitizer_libignore.cc +++ b/lib/sanitizer_common/sanitizer_libignore.cc @@ -50,23 +50,23 @@ void LibIgnore::OnLibraryLoaded(const char *name) { } // Scan suppressions list and find newly loaded and unloaded libraries. - MemoryMappingLayout proc_maps(/*cache_enabled*/false); - InternalScopedString module(kMaxPathLength); + ListOfModules modules; + modules.init(); for (uptr i = 0; i < count_; i++) { Lib *lib = &libs_[i]; bool loaded = false; - proc_maps.Reset(); - uptr b, e, off, prot; - while (proc_maps.Next(&b, &e, &off, module.data(), module.size(), &prot)) { - if ((prot & MemoryMappingLayout::kProtectionExecute) == 0) - continue; - if (TemplateMatch(lib->templ, module.data()) || - (lib->real_name && - internal_strcmp(lib->real_name, module.data()) == 0)) { + for (const auto &mod : modules) { + for (const auto &range : mod.ranges()) { + if (!range.executable) + continue; + if (!TemplateMatch(lib->templ, mod.full_name()) && + !(lib->real_name && + internal_strcmp(lib->real_name, mod.full_name()) == 0)) + continue; if (loaded) { Report("%s: called_from_lib suppression '%s' is matched against" " 2 libraries: '%s' and '%s'\n", - SanitizerToolName, lib->templ, lib->name, module.data()); + SanitizerToolName, lib->templ, lib->name, mod.full_name()); Die(); } loaded = true; @@ -75,13 +75,14 @@ void LibIgnore::OnLibraryLoaded(const char *name) { VReport(1, "Matched called_from_lib suppression '%s' against library" " '%s'\n", - lib->templ, module.data()); + lib->templ, mod.full_name()); lib->loaded = true; - lib->name = internal_strdup(module.data()); + lib->name = internal_strdup(mod.full_name()); const uptr idx = atomic_load(&loaded_count_, memory_order_relaxed); - code_ranges_[idx].begin = b; - code_ranges_[idx].end = e; + code_ranges_[idx].begin = range.beg; + code_ranges_[idx].end = range.end; atomic_store(&loaded_count_, idx + 1, memory_order_release); + break; } } if (lib->loaded && !loaded) { |