summaryrefslogtreecommitdiff
path: root/lib/lsan
diff options
context:
space:
mode:
authorAlex Shlyapnikov <alekseys@google.com>2017-10-05 21:38:33 +0000
committerAlex Shlyapnikov <alekseys@google.com>2017-10-05 21:38:33 +0000
commit11ad3b8e2ddac18fc697e434ef5b98966e8f6feb (patch)
treeae9a31606de345dab49457590ace612b5b8c1134 /lib/lsan
parenta7688a2f53cc72a27ab18a80217e0fc08b91252c (diff)
[LSan] Detect dynamic loader by its base address.
Summary: Relanding D33859, which was reverted because it has "broken LOTS of ARM/AArch64 bots for two days". If it breaks something again, please provide some pointers to broken bots, not just revert it, otherwise it's very hard to reason what's wrong with this commit. Whenever possible (Linux + glibc 2.16+), detect dynamic loader module by its base address, not by the module name matching. The current name matching approach fails on some configurations. Reviewers: eugenis Subscribers: aemerson, kubamracek, kristof.beyls, llvm-commits Differential Revision: https://reviews.llvm.org/D38600 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@315024 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/lsan')
-rw-r--r--lib/lsan/lsan_common.cc5
-rw-r--r--lib/lsan/lsan_common_linux.cc23
2 files changed, 20 insertions, 8 deletions
diff --git a/lib/lsan/lsan_common.cc b/lib/lsan/lsan_common.cc
index 622aae734..651bbe1f3 100644
--- a/lib/lsan/lsan_common.cc
+++ b/lib/lsan/lsan_common.cc
@@ -411,8 +411,9 @@ static void MarkInvalidPCCb(uptr chunk, void *arg) {
}
}
-// On Linux, handles dynamically allocated TLS blocks by treating all chunks
-// allocated from ld-linux.so as reachable.
+// On Linux, treats all chunks allocated from ld-linux.so as reachable, which
+// covers dynamically allocated TLS blocks, internal dynamic loader's loaded
+// modules accounting etc.
// Dynamic TLS blocks contain the TLS variables of dynamically loaded modules.
// They are allocated with a __libc_memalign() call in allocate_and_init()
// (elf/dl-tls.c). Glibc won't tell us the address ranges occupied by those
diff --git a/lib/lsan/lsan_common_linux.cc b/lib/lsan/lsan_common_linux.cc
index 5042c7b3a..5acff0b2d 100644
--- a/lib/lsan/lsan_common_linux.cc
+++ b/lib/lsan/lsan_common_linux.cc
@@ -23,6 +23,10 @@
#include "sanitizer_common/sanitizer_linux.h"
#include "sanitizer_common/sanitizer_stackdepot.h"
+#if SANITIZER_USE_GETAUXVAL
+#include <sys/auxv.h>
+#endif // SANITIZER_USE_GETAUXVAL
+
namespace __lsan {
static const char kLinkerName[] = "ld";
@@ -30,8 +34,12 @@ static const char kLinkerName[] = "ld";
static char linker_placeholder[sizeof(LoadedModule)] ALIGNED(64);
static LoadedModule *linker = nullptr;
-static bool IsLinker(const char* full_name) {
- return LibraryNameIs(full_name, kLinkerName);
+static bool IsLinker(const LoadedModule& module) {
+#if SANITIZER_USE_GETAUXVAL
+ return module.base_address() == getauxval(AT_BASE);
+#else
+ return LibraryNameIs(module.full_name(), kLinkerName);
+#endif // SANITIZER_USE_GETAUXVAL
}
__attribute__((tls_model("initial-exec")))
@@ -49,22 +57,25 @@ void InitializePlatformSpecificModules() {
ListOfModules modules;
modules.init();
for (LoadedModule &module : modules) {
- if (!IsLinker(module.full_name())) continue;
+ if (!IsLinker(module))
+ continue;
if (linker == nullptr) {
linker = reinterpret_cast<LoadedModule *>(linker_placeholder);
*linker = module;
module = LoadedModule();
} else {
VReport(1, "LeakSanitizer: Multiple modules match \"%s\". "
- "TLS will not be handled correctly.\n", kLinkerName);
+ "TLS and other allocations originating from linker might be "
+ "falsely reported as leaks.\n", kLinkerName);
linker->clear();
linker = nullptr;
return;
}
}
if (linker == nullptr) {
- VReport(1, "LeakSanitizer: Dynamic linker not found. "
- "TLS will not be handled correctly.\n");
+ VReport(1, "LeakSanitizer: Dynamic linker not found. TLS and other "
+ "allocations originating from linker might be falsely reported "
+ "as leaks.\n");
}
}