NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

lib/58349: tsan expects cacheline-aligned thread-local variables but ld.elf_so only supports pointer-aligned



>Number:         58349
>Category:       lib
>Synopsis:       tsan expects cacheline-aligned thread-local variables but ld.elf_so only supports pointer-aligned
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Jun 17 23:10:00 +0000 2024
>Originator:     Taylor R Campbell
>Release:        current
>Organization:
The ld.elf_aligned Foundation
>Environment:
>Description:
Fail: regexp WARNING: ThreadSanitizer: data race  not in stderr
ThreadSanitizer: CHECK failed: tsan_rtl.cpp:149 "((reinterpret_cast<uptr>(this) % 64)) == ((0))" (0x10, 0x0) (tid=16992)
ThreadSanitizer:DEADLYSIGNAL
==16992==ERROR: ThreadSanitizer: SEGV on unknown address 0x000000000017 (pc 0x7f7ff4e5d14e bp 0x7f7fffffe350 sp 0x7f7fffffe2c0 T16992)
==16992==The signal is caused by a READ memory access.
==16992==Hint: address points to the zero page.
ThreadSanitizer:DEADLYSIGNAL
ThreadSanitizer: nested bug in the same thread, aborting.

https://releng.netbsd.org/b5reports/amd64/2024/2024.06.16.19.21.46/test.html#usr.bin_cc_t_tsan_data_race_data_race

The issue is likely the following change in the gcc12 update:

 __attribute__((tls_model("initial-exec")))
-THREADLOCAL char cur_thread_placeholder[sizeof(ThreadState)] ALIGNED(64);
+THREADLOCAL char cur_thread_placeholder[sizeof(ThreadState)] ALIGNED(
+    SANITIZER_CACHE_LINE_SIZE);
...
+ThreadState::ThreadState(Context *ctx, Tid tid, int unique_id, u64 epoch,
+                         unsigned reuse_count, uptr stk_addr, uptr stk_size,
                          uptr tls_addr, uptr tls_size)
...
+  CHECK_EQ(reinterpret_cast<uptr>(this) % SANITIZER_CACHE_LINE_SIZE, 0);

http://cvsweb.netbsd.org/bsdweb.cgi/src/external/gpl3/gcc/dist/libsanitizer/tsan/tsan_rtl.cpp.diff?r1=1.2&r2=1.3&only_with_tag=MAIN

The alignment requirement is not new (the magic number 64 just got a name SANITIZER_CACHE_LINE_SIZE), but there is a new check to verify it at runtime which is now failing.
>How-To-Repeat:
cd /usr/tests/usr.bin/cc && atf-run t_tsan_data_race
>Fix:
Yes, please!

Possible options:

1. Delete the check like before.
2. Teach ld.elf_so/xmalloc.c to support larger alignments.
3. Teach ld.elf_so/tls.c to fudge larger 2^k-byte alignments for n-byte allocations by allocating n + 2^k - 1 bytes at p and returning q := (p + 2^k - 1) % 2^k.  (May require some twiddling to figure out what p was originally in order to free it later.)



Home | Main Index | Thread Index | Old Index