Skip to content

Fix #95126: io::cleanup() can panic in unusual circumstances #95181

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from

Conversation

jswrenn
Copy link
Member

@jswrenn jswrenn commented Mar 21, 2022

Fixes #95126 by modifying io::cleanup() to flush stdout without dropping its LineWriter.

@rust-highfive
Copy link
Contributor

r? @Mark-Simulacrum

(rust-highfive has picked a reviewer for you, use r? to override)

@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Mar 21, 2022
@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 21, 2022
@bors
Copy link
Collaborator

bors commented Mar 21, 2022

☔ The latest upstream changes (presumably #95180) made this pull request unmergeable. Please resolve the merge conflicts.

// leak the old, buffered LineWriter to avoid deallocations this
// ensures that writes to stdout *during* cleanup (e.g., writes
// emitted by a custom global allocator) won't deadlock (#95126)
crate::mem::forget(buffered);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I follow why this needs to be leaked -- it seems like what we need to do is make sure that the lock has been released before we drop it, but that's something that we can do easily enough (just moving the drop outside the lock.try_borrow_mut).

@@ -621,7 +621,18 @@ pub fn cleanup() {
// might have leaked a StdoutLock, which would
// otherwise cause a deadlock here.
if let Some(lock) = Pin::static_ref(instance).try_lock() {
*lock.borrow_mut() = LineWriter::with_capacity(0, stdout_raw());
if let Ok(mut refmut) = lock.try_borrow_mut() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you help me understand this try_borrow_mut? the try_lock above is justified by leaking a StdoutLock, so presumably the panic on borrow_mut() here would occur when someone leaks a locked RefCell -- but that RefCell is never exposed, and std shouldn't be leaking it (right?)...

I think this could also happen if cleanup() is invoked while the RefCell is locked on the stack above us, but I wouldn't expect that to happen either.

// replace the current LineWriter with the unbuffered one
let mut buffered = crate::mem::replace(&mut *refmut, unbuffered);
// flush the old, buffered LineWriter
let _ = buffered.flush();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would loosely expect that we should move this flushing out of the STDOUT lock.

@Mark-Simulacrum Mark-Simulacrum added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 6, 2022
@Dylan-DPC
Copy link
Member

@jswrenn any updates on this?

@Dylan-DPC
Copy link
Member

Closing this as the pr is inactive. Feel free to open a new PR if you wish to continue working on this

@Dylan-DPC Dylan-DPC closed this Jan 14, 2023
@Dylan-DPC Dylan-DPC added S-inactive Status: Inactive and waiting on the author. This is often applied to closed PRs. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jan 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-inactive Status: Inactive and waiting on the author. This is often applied to closed PRs. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

io::cleanup() can panic in unusual circumstances
6 participants