2300 Commits

Author SHA1 Message Date
David Benjamin
e6de45a229
[tsan] Don't treat uncontended pthread_once as a potentially blocking region (#132477)
guard_acquire is a helper function used to implement TSan's
__cxa_guard_acquire and pthread_once interceptors.
https://reviews.llvm.org/D54664 introduced optional hooks to support
cooperative multi-threading. It worked by marking the entire
guard_acquire call as a potentially blocking region.

In principle, only the contended case needs to be a potentially blocking
region. This didn't matter for __cxa_guard_acquire because the compiler
emits an inline fast path before calling __cxa_guard_acquire. That is,
once we call __cxa_guard_acquire at all, we know we're in the contended
case.

https://reviews.llvm.org/D107359 then unified the __cxa_guard_acquire
and pthread_once interceptors, adding the hooks to pthread_once.
However, unlike __cxa_guard_acquire, pthread_once callers are not
expected to have an inline fast path. The fast path is inside the
function.

As a result, TSan unnecessarily calls into the cooperative
multi-threading engine on every pthread_once call, despite applications
generally expecting pthread_once to be fast after initialization. Fix
this by deferring the hooks to the contended case inside guard_acquire.
2025-03-24 19:30:15 -04:00
Meng Zhuo
76910f914c
[tsan][RISCV] Add Go support for linux/riscv64 (#127295)
This is needed to support race detector in Golang.

See also: https://github.com/golang/go/issues/64345
2025-02-28 18:27:48 +08:00
Julian Lettner
a34159f85e
[TSan][Apple] Fix interceptor build error (#124351)
In certain cases, the SDK headers declare
`OSSpinLock*` APIs as macros (instead of
functions), so users can be transparently
forwarded to non-deprecated APIs.

When enabled, building of TSan interceptors failed
because these macros interfere with the
interceptor machinery, i.e., they prevent proper
forward declaration of intercepted APIs.

In a previous change [1], we misattributed this to
the deprecation of `OSSpinLock*` APIs.

[1] ae484c21c05668f84b13304c28bc39f753e493de

rdar://143193907
2025-01-27 15:48:29 -08:00
Meng Zhuo
4e81275674
[tsan] Add support for linux/riscv64 in lib/tsan/go/buildgo.sh (#124557) 2025-01-27 10:39:40 -08:00
Vitaly Buka
cd66c9b6a0
[Ubsan][Driver] Remove UBSAN C++ runtime from other sanitizers (#121006)
Linking this runtime requires C++ ABI, which breaks -nostdlib++ builds.
However, UBSAN C++ runtime is only needed for CFI and VPTR checks.

Unblocks #120370.
2024-12-24 13:57:03 -08:00
Stefan Schulze Frielinghaus
9a156f6b2b [sanitizer] Replace uptr by usize/SIZE_T in interfaces
For some targets uptr is mapped to unsigned int and size_t to unsigned
long and sizeof(int)==sizeof(long) holds.  Still, these are distinct
types and type checking may fail.  Therefore, replace uptr by
usize/SIZE_T wherever a size_t is expected.

Part of #116957
2024-12-07 20:20:27 -08:00
Vitaly Buka
5fa0345d90
[tsan] Unwind for CHECK according to fast_unwind_on_fatal (#117470)
It's needed for #116409, which hangs with slow
unwind.
2024-11-24 00:25:06 -08:00
Vitaly Buka
9254b81990
[tsan] Fix typo in type (#115769)
Introduced with #114931
Fixes https://github.com/golang/go/issues/70283
2024-11-11 13:16:27 -08:00
Alexander Richardson
5082acce4f
[compiler-rt] Add custom libc++ workaround for CMake < 3.26
The INSTALL_BYPRODUCTS ExternalProject_Add() argument was only added in
CMake 3.26 and the current minimum is 3.20. Work around this by using an
explicit ExternalProject_Add_Step() call for the install step with a
BYPRODUCTS argument. We can't keep using the `install` name here since that
is reserved by the CMake implementation and results in errors when used.

This commit should be reverted once LLVM depends on CMake 3.26.

Pull Request: https://github.com/llvm/llvm-project/pull/115677
2024-11-10 20:30:23 -08:00
Alexander Richardson
e7bad34475
[compiler-rt] Use installed libc++(abi) for tests instead of build tree
Using the build tree is somewhat fragile since the layout is not
guaranteed to be stable and means the tests are tightly coupled to the
libc++/libc++abi build tree layout. Instead update the ExternalProject
to install the library and headers and do not add the build tree to
the include/linker flags.

Pull Request: https://github.com/llvm/llvm-project/pull/115077
2024-11-06 11:57:47 -08:00
Vitaly Buka
4d374479be
[nfc][tsan] Replace some macros with templates (#114931) 2024-11-05 16:16:35 -08:00
Vitaly Buka
823625cf1d
[nfc][tsan] Simplify morder conversion (#115075)
All valid values should fit into a byte.
This slightly reduce generated code on x86_64.
2024-11-05 13:50:46 -08:00
Vitaly Buka
17d956588a
Reapply "[tsan] Don't use enum __tsan_memory_order in tsan interface"" (#115034)
In C++ it's UB to use undeclared values as enum.
And there is support __ATOMIC_HLE_ACQUIRE and
__ATOMIC_HLE_RELEASE need such values.

So use `int` in TSAN interface, and mask out
irrelevant bits and cast to enum ASAP.

`ThreadSanitizer.cpp` already declare morder parameterd
in these functions as `i32`.

This may looks like a slight change, as we
previously didn't mask out additional bits for `fmo`,
and `NoTsanAtomic` call. But from implementation
it's clear that they are expecting exact enum.


Reverts llvm/llvm-project#115032
Reapply llvm/llvm-project#114724
2024-11-05 11:23:52 -08:00
Vitaly Buka
b14c436311
Revert "[tsan] Don't use enum __tsan_memory_order in tsan interface" (#115032)
Reverts llvm/llvm-project#114724

Breaks OSX builds
2024-11-05 09:43:29 -08:00
Vitaly Buka
1e50958399
[tsan] Don't use enum __tsan_memory_order in tsan interface (#114724)
In C++ it's UB to use undeclared values as enum.
And there is support `__ATOMIC_HLE_ACQUIRE` and
`__ATOMIC_HLE_RELEASE` need such values.

Internal implementation was switched to `class enum`,
where that behavior is defined. But interface is C, so
we just switch to `int`.
2024-11-05 09:21:19 -08:00
Vitaly Buka
a9f829a3d7
[nfc][tsan] Move out morder params from __VA_ARGS__ (#114916)
In #114724 I'd like to cast from int to enum, but
existing code `mo = convert_morder(mo)` does not
allow that.
2024-11-04 21:04:57 -08:00
Vitaly Buka
fade3be83d
[nfc][tsan] Wrap Atomic/NoTsanAtomic int struct (#114909)
Prepare to replace macro with template.

Related to #114724, but it's not strictly needed.
2024-11-04 18:47:25 -08:00
Vitaly Buka
3e15454eed
[tsan] Clang format a few files (#114725) 2024-11-04 12:22:00 -08:00
Vitaly Buka
36bd9aebc4
[sanitizer] VReport BeforeFork/AfterFork (#111900)
Forks are common suspects for unusual sanitizer behavior.
It can be handy to see them without rebuild.
2024-10-10 13:12:36 -07:00
Chris Apple
a4232dc676
[rtsan][tsan] Fix va_args handling in open functions (#108291)
Check oflag to see if it contains O_CREAT / O_TMPFILE before unpacking parameters to avoid UB
2024-09-23 06:55:14 -07:00
Vitaly Buka
a0bb2e21c1
[NFC][sanitizer] Move InitTlsSize into InitializePlatformEarly (#108921) 2024-09-18 16:19:35 -07:00
Vitaly Buka
71a91c1194
[tsan] Use DlSymAllocator (#108920)
`DlSymAllocator` allows early allocations, when
tsan is not yet initialized, e.g. from `dlsym`.

All other sanitizers with interceptors already use
`DlSymAllocator`.

Existing `in_symbolizer()` tsan logic is very similar.
However, we need to keep both as `DlSymAllocator`
does not support large allocations, needed for Symolizer.
2024-09-17 11:06:26 -07:00
Vitaly Buka
f13b7d0b02
Reland "[sanitizer] Fix partially initialized static TLS range" (#108883)
Reland llvm/llvm-project#108685

Arguments order was wrong on Windows and Darwin.
2024-09-16 14:05:00 -07:00
Vitaly Buka
9a1d0744ed
Revert "[sanitizer] Fix partially initialized static TLS range" (#108881)
Reverts llvm/llvm-project#108685

Breaks Darwin and Windows
https://lab.llvm.org/buildbot/#/builders/107/builds/2930
https://ci.swift.org/view/all/job/llvm.org/view/LLDB/job/as-lldb-cmake/11684/
2024-09-16 13:51:23 -07:00
Vitaly Buka
b7c9ebe4ec
[sanitizer] Fix partially initialized static TLS range (#108685)
Fixes asan, msan crash on check added in #108684.
The #108684 includes reproducer of the issue.

Change interface of `GetThreadStackAndTls` to
set `tls_begin` and `tls_end` at the same time.
2024-09-16 12:48:24 -07:00
Vitaly Buka
bafe3a4b0c [NFC][tsan] Fix reallocarray, calloc parameters order
Implementation is commutative, so it should make
no difference. It's done just for consistency with
documentation.
2024-09-15 17:02:28 -07:00
Steven Wu
f0ef1d3bae
[CompilerRT][Darwin] Silence the warnings for deprecated APIs (#102977)
Silence deprecated API warnings in compiler-rt on Darwin platforms.
2024-08-13 09:57:25 -07:00
Vitaly Buka
89c8d68eb7
[NFC] Fix typo in REAL(pthread_join(th, ret)) (#102393)
Looks like the macro expands to the same,
but usually we do `REAL(pthread_join)(th, ret)`.
2024-08-07 15:25:55 -07:00
Florian Mayer
21648d3228 [compiler-rt] [TSan] leave BufferedStackTrace uninit
Otherwise we have to memset 2040 bytes (255 * 8) for each call

Pull Request: https://github.com/llvm/llvm-project/pull/102255
2024-08-07 15:19:27 -07:00
Fangrui Song
7bb6bb9a1f [tsan] Replace ALIGNED with alignas
Similar to #98958.

The relands 656f617ac772c54e0bee9d499e7ca232137ddb35 , which
was reverted due to an issue in tsan_platform_mac.cpp

Pull Request: https://github.com/llvm/llvm-project/pull/98959
2024-07-16 14:35:11 -07:00
Fangrui Song
898c116add [tsan] Avoid ALIGNED in tsan_platform_mac.cpp. NFC 2024-07-16 14:28:38 -07:00
Daniel Thornburgh
434c2382f1
Revert "[tsan] Replace ALIGNED with alignas" (#99240)
Reverts llvm/llvm-project#98959
2024-07-16 14:09:50 -07:00
Fangrui Song
656f617ac7
[tsan] Replace ALIGNED with alignas
Similar to #98958.

Pull Request: https://github.com/llvm/llvm-project/pull/98959
2024-07-16 10:39:46 -07:00
Fangrui Song
bb8230bb2b
[sanitizer] Internalize .preinit_array variables
We can use an internal linkage variable to make it clear the variable is
not exported. The special section .preinit_array is a GC root.

Pull Request: https://github.com/llvm/llvm-project/pull/98584
2024-07-12 11:15:46 -07:00
Thurston Dang
bbb90feb87
[tsan] Fix ASLR edge case, and improve diagnostics (#97125)
In extremely rare cases (estimated 1 in 3 million), minor allocations
that happen after the memory layout was checked in
InitializePlatformEarly() [1] may result in the memory layout
unexpectedly being incompatible in InitializePlatform(). We fix this by
adding another memory layout check (and opportunity to re-exec without
ASLR) in InitializePlatform().

To improve future debuggability, this patch also dumps the process map
if the memory layout is unexpectedly incompatible.

[1]
```
 __sanitizer::InitializePlatformEarly();
  __tsan::InitializePlatformEarly();

#if !SANITIZER_GO
  InitializeAllocator(); // <-- ~8MB mmap'ed
  ReplaceSystemMalloc();
#endif
  if (common_flags()->detect_deadlocks)
    ctx->dd = DDetector::Create(flags()); // <-- ~4MB mmap'ed
  Processor *proc = ProcCreate(); // <-- ~1MB mmap'ed
  ProcWire(proc, thr);
  InitializeInterceptors(); <-- ~3MB mmap'ed
  InitializePlatform();
```
2024-07-11 08:25:41 -07:00
Thurston Dang
4052de6cb5
[tsan] Fix calculation of shadow end address in MemoryAccessRangeT (#98404)
MemoryAccessRangeT overestimates the size of the shadow region by 8x,
occasionally leading to assertion failure:
```
  RawShadow* shadow_mem = MemToShadow(addr);
  ...
  // Check that end of shadow is valid
  if (!IsShadowMem(shadow_mem + size * kShadowCnt - 1)) {
    DCHECK(IsShadowMem(shadow_mem + size * kShadowCnt - 1));
```
It is erroneous for two separate reasons:
- it uses kShadowCnt (== 4) instead of kShadowMultiplier (== 2)
- since shadow_mem is a RawShadow*, pointer arithmetic is multiplied by
sizeof(RawShadow) == 4

This patch fixes the calculation, and also improves the debugging
information.

The assertion error was observed on a buildbot
(https://lab.llvm.org/staging/#/builders/89/builds/656/steps/13/logs/stdio):
```
Bad shadow addr 0x3000000190bc (7fffffffe85f)
ThreadSanitizer: CHECK failed: tsan_rtl_access.cpp:690 "((IsShadowMem(shadow_mem + size * kShadowCnt - 1))) != (0)" (0x0, 0x0) (tid=2202676)
```
Notice that 0x3000000190bc is not the correct shadow for the end address
0x7fffffffe85f.

This error is more commonly observed on high-entropy ASLR systems, since
ASLR may be disabled (if the randomized memory layout is incompatible),
leading to an allocation near the boundaries of the high app memory
region (and therefore a shadow end that may be erroneously calculated to
be past the end of the shadow region). Also note that the assertion is
guarded by SANITIZER_DEBUG.

---------

Co-authored-by: Vitaly Buka <vitalybuka@gmail.com>
2024-07-10 19:34:14 -07:00
Tulio Magno Quites Machado Filho
7b34070eb4
[tsan][aarch64] Fix branch protection in interceptors (#95839)
Start functions with BTI in order to identify the function as a valid
branch target.
Also add the BTI marker to tsan_rtl_aarch64.S.

With this patch, libclang_rt.tsan.so can now be generated with
DT_AARCH64_BTI_PLT when built with -mbranch-protection=standard.
2024-07-01 10:23:45 -03:00
Vitaly Buka
c0dc134de5
[tsan] Lock/Unlock allocator and stacks on fork (#96600)
We do that for other Sanitizers, and we
should do the same for TSAN.
There are know deadlocks reports here.
2024-06-25 10:05:25 -07:00
Vitaly Buka
0258a60cd9
[nfc][tsan] Clang format includes (#96599) 2024-06-25 10:03:12 -07:00
Vitaly Buka
cd2bac81a9
[nfc][tsan] Better name for locking functions (#96598)
These functions used only for `fork`.

Unused parameter `child` will be used in followup patches.
2024-06-25 10:02:01 -07:00
Vitaly Buka
0b049ce646
[tsan] Test __tsan_test_only_on_fork only on Mac (#96597)
According to https://reviews.llvm.org/D114250
this was to handle Mac specific issue, however
the test is Linux only.

The test effectively prevents to lock main allocator
on fork, but we do that on Linux for other
sanitizers for years, and need to do the same
for TSAN to avoid deadlocks.
2024-06-25 09:58:32 -07:00
Vitaly Buka
f0f774ebf0
[sanitizer] Rename DEFINE_REAL_PTHREAD_FUNCTIONS (#96527)
We use REAL() calls in interceptors, but
DEFINE_REAL_PTHREAD_FUNCTIONS has nothing to do
with them and only used for internal maintenance
threads.

This is done to avoid confusion like in #96456.
2024-06-25 09:42:01 -07:00
Vitaly Buka
7f10ed637e
[tsan] Fix dead lock when starting StackDepot thread (#96456)
Sometime tsan runtimes calls, like
`__tsan_mutex_create ()`, need to store a stack
in the StackDepot, and the Depot may need to start
and maintenance thread.

Example:
```
__sanitizer::FutexWait ()
__sanitizer::Semaphore::Wait ()
__sanitizer::Mutex::Lock ()
__tsan::SlotLock ()
__tsan::SlotLocker::SlotLocker ()
__tsan::Acquire ()
__tsan::CallUserSignalHandler ()
__tsan::ProcessPendingSignalsImpl ()
__tsan::ProcessPendingSignals ()
__tsan::ScopedInterceptor::~ScopedInterceptor ()
___interceptor_mmap ()
pthread_create ()
__sanitizer::internal_start_thread ()
__sanitizer::(anonymous namespace)::CompressThread::NewWorkNotify ()
__sanitizer::StackDepotNode::store ()
__sanitizer::StackDepotBase<__sanitizer::StackDepotNode, 1, 20>::Put ()
__tsan::CurrentStackId ()
__tsan::MutexCreate ()
__tsan_mutex_create ()
```

pthread_create() implementation may hit other
interceptors recursively, which may invoke
ProcessPendingSignals, which deadlocks.

Alternative solution could be block interceptors
closer to TSAN runtime API function, like
`__tsan_mutex_create`, or just before
`StackDepotPut``, but it's not needed for most
calls, only when new thread is created using
`real_pthread_create`.

I don't see a reasonable way to create a
regression test.
2024-06-25 08:17:10 -07:00
Michael Kruse
a35ac42fac
[compiler-rt] Revise IDE folder structure (#89753)
Update the folder titles for targets in the monorepository that have not
seen taken care of for some time. These are the folders that targets are
organized in Visual Studio and XCode
(`set_property(TARGET <target> PROPERTY FOLDER "<title>")`)
when using the respective CMake's IDE generator.

 * Ensure that every target is in a folder
 * Use a folder hierarchy with each LLVM subproject as a top-level folder
 * Use consistent folder names between subprojects
 * When using target-creating functions from AddLLVM.cmake, automatically
deduce the folder. This reduces the number of
`set_property`/`set_target_property`, but are still necessary when
`add_custom_target`, `add_executable`, `add_library`, etc. are used. A
LLVM_SUBPROJECT_TITLE definition is used for that in each subproject's
root CMakeLists.txt.
2024-06-04 09:26:45 +02:00
Fangrui Song
d5224b73cc
[tsan] Refine fstat{,64} interceptors (#86625)
In glibc versions before 2.33. `libc_nonshared.a` defines
`__fxstat/__fxstat64` but there is no `fstat/fstat64`. glibc 2.33 added
`fstat/fstat64` and obsoleted `__fxstat/__fxstat64`. Ports added after
2.33 do not provide `__fxstat/__fxstat64`, so our `fstat/fstat64`
interceptors using `__fxstat/__fxstat64` interceptors would lead to
runtime failures on such ports (LoongArch and certain RISC-V ports).

Similar to https://reviews.llvm.org/D118423, refine the conditions that
we define fstat{,64} interceptors. `fstat` is supported by musl/*BSD
while `fstat64` is glibc only.
2024-03-26 14:09:39 -07:00
Nazım Can Altınova
fe97a6148e
[tsan] Add callbacks for futex syscalls and mark them as blocking on tsan (#86537)
Fixes #83844.

This PR adds callbacks to mark futex syscalls as blocking. Unfortunately
we didn't have a mechanism before to mark syscalls as a blocking call,
so I had to implement it, but it mostly reuses the `BlockingCall`
implementation
[here](96819daa3d/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp (L362-L380)).

The issue includes some information but this issue was discovered
because Rust uses futexes directly. So most likely we need to update
Rust as well to use these callbacks.

Also see the latest comments in #85188 for some context.
I also sent another PR #84162 to mark `pthread_*_lock` calls as
blocking.
2024-03-26 12:33:51 +01:00
Nazım Can Altınova
f01377d8eb
[tsan] Mark pthread_*_lock functions as blocking (#84162)
Fixes #83561.

When a thread is blocked on a mutex and we send an async signal to that
mutex, it never arrives because tsan thinks that `pthread_mutex_lock` is
not a blocking function. This patch marks `pthread_*_lock` functions as
blocking so we can successfully deliver async signals like `SIGPROF`
when the thread is blocked on them.

See the issue also for more details. I also added a test, which is a
simplified version of the compiler explorer example I posted in the
issue.

Please let me know if you have any other ideas or things to improve!
Happy to work on them.

Also I filed #83844 which is more tricky because we don't have a libc
wrapper for `SYS_futex`. I'm not sure how to intercept this yet. Please
let me know if you have ideas on that as well. Thanks!
2024-03-26 12:32:52 +01:00
Vitaly Buka
4acd84e7cc
Revert "[compiler-rt] Also consider SIGPROF as a synchronous signal" (#86416)
Reverting #85188 with follow up patches.

This reverts commit 362d26366d0175f01ffb6085eb747a6e40f01147.
This reverts commit c9bdeabdf4b46fbf1f6a9fcbf9cd61d460b18c08.
This reverts commit 6bc6e1ace9fa8453e164fa04b5d9acd5a77e089a.
This reverts commit 01fa550ff654d6724e6da54c877032baeddff14b.
This reverts commit ddcbab37ac0e5743a8d39be3dd48d967f4c85504.
2024-03-24 01:22:48 -07:00
Vitaly Buka
362d26366d
[tsan] Process SIGPROF as sync signal only if thread is alive (#86343)
Otherwise it may crash too early.

This is followup to #85188
2024-03-22 15:24:44 -07:00
Vitaly Buka
0ba678a53d
[tsan] Set thr->is_inited after SlotAttachAndLock (#86342)
Almost NFC.

This is symmetrical to `ThreadFinish`, which
resets the slot after `is_inited`.
2024-03-22 15:12:09 -07:00