-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Try to write the panic message with a single write_all
call
#122565
base: master
Are you sure you want to change the base?
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
The Miri subtree was changed cc @rust-lang/miri |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
let mut cursor = crate::io::Cursor::new(&mut buffer[..]); | ||
|
||
let write_msg = |dst: &mut dyn crate::io::Write| { | ||
writeln!(dst, "\nthread '{name}' panicked at {location}:\n{msg}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest to separate the functional change (more newlines) from the implementation change. Makes it easier to discuss and decide on these separately.
A leading newline is not very common in Rust output, so if it stays it definitely needs a comment explaining the purpose.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Panic output isn't stable. There's some work to add thread IDs to the panic message for example.
Yeah the extra newline is unusual, but this is an unsynchronized write to a shared output so we don't have many options to clean up the formatting in cases where a panic is emitted in the middle of something else that's printing.
proc_macro_generated_packed.stderr
is a good example of this. It start printing the panic message in the middle of reporting another error.
Do you think it's disruptive enough that it warrants separate discussion?
Some changes occurred in run-make tests. cc @jieyouxu |
☔ The latest upstream changes (presumably #122267) made this pull request unmergeable. Please resolve the merge conflicts. |
Would it be possible(or too overkill?) to check how much stack is left(but without using external crate) and if enough only then write to the on-stack buffer, else write to I sort of tried to look into it, preliminarily, and it seems that (perhaps due to println!? unsure) it needs >=816 bytes left on reported stack or it will stack overflow in this example: output is like this on linux/gentoo:
|
If we reserve a 512 byte buffer on the stack, then we don't have a guarantee that the compiler doesn't emit code that forces using 512 bytes deeper into the stack even on the codepath that does not write to that (as it may do something like, for instance, |
I'm not sure I understand that ^, which leads me to say this: but isn't the buffer only allocated on the stack if the specific closure gets to execute? assuming the buffer is inside that closure which we wouldn't execute in the case when we'd know there's not enough stack left for it. |
Speaking very broadly... please do not take this as a gospel fact in all cases, but rather as more "Jubilee's understanding of the underlying principles at work, as she has derived from experience (and sometimes talking to LLVM devs)"... LLVM does not view itself as beholden to concerns like "have we run out of stack?" when performing optimizations. That means it is basically always valid to hoist constant byte arrays like that to earlier. That in itself wouldn't mean we allocate a bunch of extra stack always... but by and large, our closures tend to optimize well because they are inlined into the function that calls them, which means that the enclosing function and the closure are optimized together into a single call. We have to apply many annotations to discourage this behavior. This doesn't mean LLVM loves optimizing byte arrays on the stack so much it will always do this, it's just that when it's about, like... 512 bytes? I don't think checking if we have 512 bytes available is worth the other costs. |
on a less "what are legal program optimizations?" level: in general the stack is chunked into pages of 4KB or more, so using stacker to check for less than 4kb left of stack is... a little silly. |
rust-lang/rust#122565 adds a new line to thread panic output. To make the current test suites works on stable, beta, and nightly, this relaxes the assertion around that by globbing everything.
rust-lang/rust#122565 adds a new line to thread panic output. To make the current test suites works on stable, beta, and nightly, this relaxes the assertion around that by globbing everything.
Thought somebody will post a PR instead 😆. Anyhow, I have just opened one: rust-lang/cargo#14602. |
test: relax panic output assertion ### What does this PR try to resolve? rust-lang/rust#122565 adds a new line to thread panic output. To make the current test suites works on stable, beta, and nightly, this relaxes the assertion around that by globbing everything. ### How should we test and review this PR? Switch to rust-lang/rust#122565 and build a stage0 std, then use it to run these Cargo tests. Linking to stage0 toolchain should work: https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html#creating-a-rustup-toolchain
This could use another try run now. |
@bors try |
Try to write the panic message with a single `write_all` call This writes the panic message to a buffer before writing to stderr. This allows it to be printed with a single `write_all` call, preventing it from being interleaved with other outputs. It also adds newlines before and after the message ensuring that only the panic message will have its own lines. Before: ``` thread 'thread 'thread 'thread 'thread '<unnamed>thread 'thread 'thread 'thread '<unnamed><unnamed>thread '<unnamed>' panicked at ' panicked at <unnamed><unnamed><unnamed><unnamed><unnamed>' panicked at <unnamed>' panicked at src\heap.rssrc\heap.rs' panicked at ' panicked at ' panicked at ' panicked at ' panicked at src\heap.rs' panicked at src\heap.rs::src\heap.rssrc\heap.rssrc\heap.rssrc\heap.rssrc\heap.rs:src\heap.rs:455455:::::455:455::455455455455455:455:99:::::9:9: : 999: 999: assertion failed: size <= (*queue).block_size: : assertion failed: size <= (*queue).block_size: assertion failed: size <= (*queue).block_size: : : assertion failed: size <= (*queue).block_sizeassertion failed: size <= (*queue).block_sizeassertion failed: size <= (*queue).block_size assertion failed: size <= (*queue).block_size assertion failed: size <= (*queue).block_sizeassertion failed: size <= (*queue).block_sizeerror: process didn't exit successfully: `target\debug\direct_test.exe` (exit code: 0xc0000409, STATUS_STACK_BUFFER_OVERRUN) ``` After: ``` thread '<unnamed>' panicked at src\heap.rs:455:9: assertion failed: size <= (*queue).block_size thread '<unnamed>' panicked at src\heap.rs:455:9: assertion failed: size <= (*queue).block_size thread '<unnamed>' panicked at src\heap.rs:455:9: assertion failed: size <= (*queue).block_size error: process didn't exit successfully: `target\debug\direct_test.exe` (exit code: 0xc0000409, STATUS_STACK_BUFFER_OVERRUN) ``` r? `@the8472` try-job: x86_64-gnu-aux
☀️ Try build successful - checks-actions |
@rustbot ready |
86fc657
to
a59ae4c
Compare
Rebased and reblessed. @bors r+ |
Try to write the panic message with a single `write_all` call This writes the panic message to a buffer before writing to stderr. This allows it to be printed with a single `write_all` call, preventing it from being interleaved with other outputs. It also adds newlines before and after the message ensuring that only the panic message will have its own lines. Before: ``` thread 'thread 'thread 'thread 'thread '<unnamed>thread 'thread 'thread 'thread '<unnamed><unnamed>thread '<unnamed>' panicked at ' panicked at <unnamed><unnamed><unnamed><unnamed><unnamed>' panicked at <unnamed>' panicked at src\heap.rssrc\heap.rs' panicked at ' panicked at ' panicked at ' panicked at ' panicked at src\heap.rs' panicked at src\heap.rs::src\heap.rssrc\heap.rssrc\heap.rssrc\heap.rssrc\heap.rs:src\heap.rs:455455:::::455:455::455455455455455:455:99:::::9:9: : 999: 999: assertion failed: size <= (*queue).block_size: : assertion failed: size <= (*queue).block_size: assertion failed: size <= (*queue).block_size: : : assertion failed: size <= (*queue).block_sizeassertion failed: size <= (*queue).block_sizeassertion failed: size <= (*queue).block_size assertion failed: size <= (*queue).block_size assertion failed: size <= (*queue).block_sizeassertion failed: size <= (*queue).block_sizeerror: process didn't exit successfully: `target\debug\direct_test.exe` (exit code: 0xc0000409, STATUS_STACK_BUFFER_OVERRUN) ``` After: ``` thread '<unnamed>' panicked at src\heap.rs:455:9: assertion failed: size <= (*queue).block_size thread '<unnamed>' panicked at src\heap.rs:455:9: assertion failed: size <= (*queue).block_size thread '<unnamed>' panicked at src\heap.rs:455:9: assertion failed: size <= (*queue).block_size error: process didn't exit successfully: `target\debug\direct_test.exe` (exit code: 0xc0000409, STATUS_STACK_BUFFER_OVERRUN) ```
The job Click to see the possible cause of the failure (guessed by this bot)
|
💔 Test failed - checks-actions |
☔ The latest upstream changes (presumably #129582) made this pull request unmergeable. Please resolve the merge conflicts. |
@bors r- (bors sync) |
This writes the panic message to a buffer before writing to stderr. This allows it to be printed with a single
write_all
call, preventing it from being interleaved with other outputs. It also adds newlines before and after the message ensuring that only the panic message will have its own lines.Before:
After: