-
-
Notifications
You must be signed in to change notification settings - Fork 15.4k
Inappropriate panic!s in Thread::new on certain unix platforms #160793
Copy link
Copy link
Open
Labels
A-threadArea: `std::thread`Area: `std::thread`C-bugCategory: This is a bug.Category: This is a bug.I-memleakIssue: Runtime memory leak without `mem::forget`.Issue: Runtime memory leak without `mem::forget`.I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}Issue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessT-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.This issue may need triage. Remove it if it has been sufficiently triaged.
Description
Metadata
Metadata
Assignees
Labels
A-threadArea: `std::thread`Area: `std::thread`C-bugCategory: This is a bug.Category: This is a bug.I-memleakIssue: Runtime memory leak without `mem::forget`.Issue: Runtime memory leak without `mem::forget`.I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}Issue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessT-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.This issue may need triage. Remove it if it has been sufficiently triaged.
Found after discussing code surrounding #160219 on zulip.
Edit: It is inappropriate for
Thread::newto ever panic, because we guarantee thatthread::current, which uses it, does not call the global allocator reentrantly. The memory leak on unwind, which this issue was originally about, is not that important.The implementation of
Thread::newmanually initializes a struct behindMaybeUninit, which means that ifParker::new_in_placeunwinds, thename's memory (essentiallyOption<CString>), now held by the previously writtennamefield behindMaybeUninit, is leaked.rust/library/std/src/thread/thread.rs
Lines 101 to 108 in 4667d75
Note that this is possible, on certain unix platforms:
rust/library/std/src/sys/sync/thread_parking/pthread.rs
Lines 24 to 32 in 4667d75
which calls
rust/library/std/src/sys/pal/unix/sync/condvar.rs
Lines 152 to 175 in 4667d75
which uses
assert_eqto ensure that the initialization of theCondvarsucceeds (it can fail, e.g. from resource exhaustion). Note that the method itself expects failures are possible here. It uses a guard struct to ensure that the resources of the condattr are not leaked on unwind.Furthermore, the implementation of
std::thread::currentseems to assume thatThread::newnever unwinds, because it sets a flag to detect reentrance, which is never reset if an unwind occurs:rust/library/std/src/thread/current.rs
Lines 289 to 301 in 4667d75
The first issue should be fixable by reordering the fields' initialization logic, and the second one by adding a drop guard that unsets the busy state.