Skip to content

[TSan] futex syscalls are not marked as blocking, causing hangs on TSan builds when combined with async signals #123138

Open
@canova

Description

@canova

I've been investigating the Firefox Profiler hangs that were happening in TSan builds, and discovered that LLVM doesn't correctly mark some blocking functions calls (llvm/llvm-project#83561 and llvm/llvm-project#83844). And it was failing to send async signals like SIGPROF properly.

There is also a Rust test case in the second issue if you want to try it yourself: https://github.com/canova/rustc-tsan-testcase

They've been resolved now, but Rust needs to get the LLVM patches as well and on top of it it needs to do a manual handling for FUTEX_WAIT syscalls.

It looks like for calling syscalls directly, there isn't a way to intercept the call (it's possible for glibc calls like pthread_mutex_lock etc.). That's why when a syscall is being called, the program itself has to inject pre/post syscall hooks itself. My PR added these new hooks for futex syscalls so they can be marked as blocking properly. Rust std library also calls FUTEX_WAIT syscalls directly, which means that we need to add __sanitizer_syscall_pre_futex and __sanitizer_syscall_post_futex to here (beware that these are macros, so you'll want to cal the functions that the macros call instead):

// Use FUTEX_WAIT_BITSET rather than FUTEX_WAIT to be able to give an
// absolute time rather than a relative time.
libc::syscall(
libc::SYS_futex,
futex as *const AtomicU32,
libc::FUTEX_WAIT_BITSET | libc::FUTEX_PRIVATE_FLAG,
expected,
timespec.as_ref().map_or(null(), |t| t as *const libc::timespec),
null::<u32>(), // This argument is unused for FUTEX_WAIT_BITSET.
!0u32, // A full bitmask, to make it behave like a regular FUTEX_WAIT.
)

I tried implementing it, but I couldn't make the linker happy yet. It can't find the hooks, they should be inside the libclang_rt but I can't seem to make it work. Any help would be appreciated!

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-sanitizersArea: Sanitizers for correctness and code qualityC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions