Skip to content
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

std: Prevent print panics when using TLS #29491

Merged
merged 1 commit into from Nov 6, 2015

Conversation

@alexcrichton
Copy link
Member

@alexcrichton alexcrichton commented Oct 31, 2015

Currently if a print happens while a thread is being torn down it may cause a
panic if the LOCAL_STDOUT TLS slot has been destroyed by that point. This adds a
guard to check and prints to the process stdout if that's the case (as we do for
if the slot is already borrowed).

Closes #29488

Currently if a print happens while a thread is being torn down it may cause a
panic if the LOCAL_STDOUT TLS slot has been destroyed by that point. This adds a
guard to check and prints to the process stdout if that's the case (as we do for
if the slot is already borrowed).

Closes #29488
@rust-highfive
Copy link
Collaborator

@rust-highfive rust-highfive commented Oct 31, 2015

r? @brson

(rust_highfive has picked a reviewer for you, use r? to override)

//
// If, however, the actual I/O causes an error, we do indeed panic.
let result = match LOCAL_STDOUT.state() {
LocalKeyState::Uninitialized |

This comment has been minimized.

@nagisa

nagisa Oct 31, 2015
Contributor

LOCAL_STDOUT.with would initialize data, so I think this branch should go together with the next arm.

EDIT: this is also fine, because if stdout ends up actually changed from the global default, it would also get initialised.

This comment has been minimized.

@alexcrichton

alexcrichton Oct 31, 2015
Author Member

Yeah this branch could actually go either way, but I figured that we may as well avoid initializing TLS if we're not gonna use it anyway (e.g. as you also mentioned it'd just go to the same place regardless)

LocalKeyState::Destroyed => stdout().write_fmt(args),
LocalKeyState::Valid => {
LOCAL_STDOUT.with(|s| {
if s.borrow_state() == BorrowState::Unused {

This comment has been minimized.

@nagisa

nagisa Oct 31, 2015
Contributor

IMHO this should block waiting (using e.g. a spinlock) rather than falling back to global stdout.

This comment has been minimized.

@nagisa

nagisa Oct 31, 2015
Contributor

Ah, never mind me, this is fine, since there’s rarely a case where LOCAL_STDOUT happens to not be global stdout and two levels of locks isn’t really good.

This comment has been minimized.

@alexcrichton

alexcrichton Oct 31, 2015
Author Member

Yeah and currently the only way that this can be in use is if the same thread is already printing (e.g. somewhere up on the stack someone called println!), so we can't actually wait for the resource to become available here because it never will.

This is akin to calling println! in a Display implementation.

@nagisa
Copy link
Contributor

@nagisa nagisa commented Oct 31, 2015

LGTM. Would r+.

@sfackler
Copy link
Member

@sfackler sfackler commented Oct 31, 2015

Do we still use LOCAL_STDOUT? Can we kill it instead?

@alexcrichton
Copy link
Member Author

@alexcrichton alexcrichton commented Oct 31, 2015

@sfackler currently it's used to still capture the stdout of tests, but that's the only use that I know of.

@alexcrichton
Copy link
Member Author

@alexcrichton alexcrichton commented Nov 5, 2015

ping r? @brson

@brson
Copy link
Contributor

@brson brson commented Nov 5, 2015

@bors r+

@bors
Copy link
Contributor

@bors bors commented Nov 5, 2015

📌 Commit 8588654 has been approved by brson

@bors
Copy link
Contributor

@bors bors commented Nov 6, 2015

Testing commit 8588654 with merge 7512808...

bors added a commit that referenced this pull request Nov 6, 2015
Currently if a print happens while a thread is being torn down it may cause a
panic if the LOCAL_STDOUT TLS slot has been destroyed by that point. This adds a
guard to check and prints to the process stdout if that's the case (as we do for
if the slot is already borrowed).

Closes #29488
@bors bors merged commit 8588654 into rust-lang:master Nov 6, 2015
2 checks passed
2 checks passed
continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details
@alexcrichton alexcrichton deleted the alexcrichton:avoid-stdio-tls branch Jan 21, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

6 participants