summaryrefslogtreecommitdiff
path: root/lib/sanitizer_common/sanitizer_libignore.cc
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2016-11-22 09:49:11 +0000
committerDmitry Vyukov <dvyukov@google.com>2016-11-22 09:49:11 +0000
commit48015d4e1a1d15e38e39516815fd6f9a80dc81b3 (patch)
treec6ff0d6d8b4b96d2dd936bf1ca225ec6cbb73166 /lib/sanitizer_common/sanitizer_libignore.cc
parentf86bd316cab5a4947a8cc01a14b885503ca60de7 (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.cc31
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) {