diff options
-rw-r--r-- | lib/sanitizer_common/sanitizer_libignore.cc | 21 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_libignore.h | 3 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_interceptors.cc | 4 |
3 files changed, 21 insertions, 7 deletions
diff --git a/lib/sanitizer_common/sanitizer_libignore.cc b/lib/sanitizer_common/sanitizer_libignore.cc index 9a0213e7..82841318 100644 --- a/lib/sanitizer_common/sanitizer_libignore.cc +++ b/lib/sanitizer_common/sanitizer_libignore.cc @@ -38,7 +38,12 @@ void LibIgnore::Init(const SuppressionContext &supp) { } } -void LibIgnore::OnLibraryLoaded() { +void LibIgnore::OnLibraryLoaded(const char *name) { + const char *real_name = 0; + InternalScopedBuffer<char> buf(4096); + if (name != 0 && internal_readlink(name, buf.data(), buf.size() - 1) > 0) + real_name = buf.data(); + BlockingMutexLock lock(&mutex_); MemoryMappingLayout proc_maps(/*cache_enabled*/false); InternalScopedBuffer<char> fn(4096); @@ -48,8 +53,14 @@ void LibIgnore::OnLibraryLoaded() { proc_maps.Reset(); uptr b, e, off, prot; while (proc_maps.Next(&b, &e, &off, fn.data(), fn.size(), &prot)) { - if ((prot & MemoryMappingLayout::kProtectionExecute) != 0 && - TemplateMatch(lib->templ, fn.data())) { + bool symlink = false; + if (((prot & MemoryMappingLayout::kProtectionExecute) != 0) && + (TemplateMatch(lib->templ, fn.data()) || + // Resolve symlinks. + (real_name != 0 && real_name[0] != 0 && + TemplateMatch(lib->templ, name) && + internal_strcmp(real_name, fn.data()) == 0 && + (symlink = true)))) { if (loaded) { Report("%s: called_from_lib suppression '%s' is matched against" " 2 libraries: '%s' and '%s'\n", @@ -60,6 +71,8 @@ void LibIgnore::OnLibraryLoaded() { if (!lib->loaded) { lib->loaded = true; lib->name = internal_strdup(fn.data()); + if (symlink) + lib->real_name = internal_strdup(real_name); const uptr idx = atomic_load(&loaded_count_, memory_order_relaxed); code_ranges_[idx].begin = b; code_ranges_[idx].end = e; @@ -77,7 +90,7 @@ void LibIgnore::OnLibraryLoaded() { } void LibIgnore::OnLibraryUnloaded() { - OnLibraryLoaded(); + OnLibraryLoaded(0); } } // namespace __sanitizer diff --git a/lib/sanitizer_common/sanitizer_libignore.h b/lib/sanitizer_common/sanitizer_libignore.h index 4e6f5a97..8e1d584d 100644 --- a/lib/sanitizer_common/sanitizer_libignore.h +++ b/lib/sanitizer_common/sanitizer_libignore.h @@ -33,7 +33,7 @@ class LibIgnore { void Init(const SuppressionContext &supp); // Must be called after a new dynamic library is loaded. - void OnLibraryLoaded(); + void OnLibraryLoaded(const char *name); // Must be called after a dynamic library is unloaded. void OnLibraryUnloaded(); @@ -45,6 +45,7 @@ class LibIgnore { struct Lib { char *templ; char *name; + char *real_name; // target of symlink bool loaded; }; diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc index 596664bd..e28b9d25 100644 --- a/lib/tsan/rtl/tsan_interceptors.cc +++ b/lib/tsan/rtl/tsan_interceptors.cc @@ -136,7 +136,7 @@ static LibIgnore *libignore() { void InitializeLibIgnore() { libignore()->Init(*GetSuppressionContext()); - libignore()->OnLibraryLoaded(); + libignore()->OnLibraryLoaded(0); } } // namespace __tsan @@ -263,7 +263,7 @@ TSAN_INTERCEPTOR(void*, dlopen, const char *filename, int flag) { thr->in_rtl = 0; void *res = REAL(dlopen)(filename, flag); thr->in_rtl = 1; - libignore()->OnLibraryLoaded(); + libignore()->OnLibraryLoaded(filename); return res; } |