diff options
| author | Alexey Samsonov <vonosmas@gmail.com> | 2016-01-14 18:50:09 +0000 |
|---|---|---|
| committer | Alexey Samsonov <vonosmas@gmail.com> | 2016-01-14 18:50:09 +0000 |
| commit | 5535c5160675b720fc636a94c64685fc9be9e9ad (patch) | |
| tree | 250470d1fed22fe953a2bb2a8a7d5d983c96532e /compiler-rt/lib/lsan/lsan_common.cc | |
| parent | a9e2383528d62caa2851bbda0952e3cab44f65b9 (diff) | |
| download | bcm5719-llvm-5535c5160675b720fc636a94c64685fc9be9e9ad.tar.gz bcm5719-llvm-5535c5160675b720fc636a94c64685fc9be9e9ad.zip | |
[LSan] Use __tls_get_addr interceptor to keep track of dynamic TLS.
Summary:
We have a way to keep track of allocated DTLS segments: let's use it
in LSan. Although this code is fragile and relies on glibc
implementation details, in some cases it proves to be better than
existing way of tracking DTLS in LSan: marking as "reachable" all
memory chunks allocated directly by "ld".
The plan is to eventually get rid of the latter, once we are sure
it's safe to remove.
Reviewers: kcc
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D16164
llvm-svn: 257785
Diffstat (limited to 'compiler-rt/lib/lsan/lsan_common.cc')
| -rw-r--r-- | compiler-rt/lib/lsan/lsan_common.cc | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/compiler-rt/lib/lsan/lsan_common.cc b/compiler-rt/lib/lsan/lsan_common.cc index 1cffac44395..a7eab15b826 100644 --- a/compiler-rt/lib/lsan/lsan_common.cc +++ b/compiler-rt/lib/lsan/lsan_common.cc @@ -23,6 +23,7 @@ #include "sanitizer_common/sanitizer_stacktrace.h" #include "sanitizer_common/sanitizer_suppressions.h" #include "sanitizer_common/sanitizer_report_decorator.h" +#include "sanitizer_common/sanitizer_tls_get_addr.h" #if CAN_SANITIZE_LEAKS namespace __lsan { @@ -185,9 +186,10 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads, uptr os_id = static_cast<uptr>(suspended_threads.GetThreadID(i)); LOG_THREADS("Processing thread %d.\n", os_id); uptr stack_begin, stack_end, tls_begin, tls_end, cache_begin, cache_end; + DTLS *dtls; bool thread_found = GetThreadRangesLocked(os_id, &stack_begin, &stack_end, &tls_begin, &tls_end, - &cache_begin, &cache_end); + &cache_begin, &cache_end, &dtls); if (!thread_found) { // If a thread can't be found in the thread registry, it's probably in the // process of destruction. Log this event and move on. @@ -238,6 +240,17 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads, if (tls_end > cache_end) ScanRangeForPointers(cache_end, tls_end, frontier, "TLS", kReachable); } + if (dtls) { + for (uptr j = 0; j < dtls->dtv_size; ++j) { + uptr dtls_beg = dtls->dtv[j].beg; + uptr dtls_end = dtls_beg + dtls->dtv[j].size; + if (dtls_beg < dtls_end) { + LOG_THREADS("DTLS %zu at %p-%p.\n", j, dtls_beg, dtls_end); + ScanRangeForPointers(dtls_beg, dtls_end, frontier, "DTLS", + kReachable); + } + } + } } } } |

