Skip to content

Commit 9b068a2

Browse files
committed
[lsan] Expand a comment to document our dynamic TLS hack.
llvm-svn: 199900
1 parent 1d028b8 commit 9b068a2

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

compiler-rt/lib/lsan/lsan_common_linux.cc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,21 @@ static void ProcessPlatformSpecificAllocationsCb(uptr chunk, void *arg) {
130130

131131
// Handles dynamically allocated TLS blocks by treating all chunks allocated
132132
// from ld-linux.so as reachable.
133+
// Dynamic TLS blocks contain the TLS variables of dynamically loaded modules.
134+
// They are allocated with a __libc_memalign() call in allocate_and_init()
135+
// (elf/dl-tls.c). Glibc won't tell us the address ranges occupied by those
136+
// blocks, but we can make sure they come from our own allocator by intercepting
137+
// __libc_memalign(). On top of that, there is no easy way to reach them. Their
138+
// addresses are stored in a dynamically allocated array (the DTV) which is
139+
// referenced from the static TLS. Unfortunately, we can't just rely on the DTV
140+
// being reachable from the static TLS, and the dynamic TLS being reachable from
141+
// the DTV. This is because the initial DTV is allocated before our interception
142+
// mechanism kicks in, and thus we don't recognize it as allocated memory. We
143+
// can't special-case it either, since we don't know its size.
144+
// Our solution is to include in the root set all allocations made from
145+
// ld-linux.so (which is where allocate_and_init() is implemented). This is
146+
// guaranteed to include all dynamic TLS blocks (and possibly other allocations
147+
// which we don't care about).
133148
void ProcessPlatformSpecificAllocations(Frontier *frontier) {
134149
if (!flags()->use_tls) return;
135150
if (!linker) return;

0 commit comments

Comments
 (0)