rust-lang / rust-lang/rust

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

Open
#123,138 8 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-sanitizers C-bug T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

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 (https://github.com/llvm/llvm-project/issues/83561 and https://github.com/llvm/llvm-project/issues/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):
https://github.com/rust-lang/rust/blob/10a7aa14fed9b528b74b0f098c4899c37c09a9c7/library/std/src/sys/pal/unix/futex.rs#L60-L70

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!

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with library/std/src/sys/pal/unix/futex.rs at the FUTEX_WAIT calls and the linked LLVM sanitizer syscall hook definition. Check how the pre/post futex hooks are exposed and why the attempted integration cannot link; done means the hooks link successfully and the Rust TSan test case no longer hangs with async signals.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.