Closed
Description
I tried this code:
struct Foo;
impl Drop for Foo {
fn drop(&mut self) {
panic!("drop");
}
}
fn main() {
let f = Foo;
panic!("main");
}
9 | / fn main() {
10 | | let f = Foo;
11 | | panic!("main");
12 | | }
| |_^ panic in a function that cannot unwind
Clearly the function panics so the error message doesn't make much sense. I believe it's saying that while panicking, the function is placed into a context in which nested panics are disallowed. Perhaps the message could include a hint that says something like Possibly caused by nested panics from a drop function
.
Activity
SUPERCILEX commentedon Aug 18, 2023
cc @RalfJung
SUPERCILEX commentedon Aug 18, 2023
Mmmm, actually this doesn't have anything to do with miri. Simply executing this code produces
thread caused non-unwinding panic. aborting.
. It'd be nice if these error messages could hint that the problem may be a panic inside a drop function while handling another panic. Took me a while to figure out that bug for code I was working on.[-]Very confusing error message from Miri when panicking during a panic[/-][+]Very confusing error message when panicking during a panic[/+]asquared31415 commentedon Aug 18, 2023
This changed in 1.71:
1.70.0 output:
1.71.0 output:
1.71.0 stabilized C-unwind in #106075 (feature tracked in #74990), and that's what I expect this change to bisect to (though I haven't done any actual bisection)
It would be nice if the old message could be restored, the message "thread panicked while panicking. aborting." is significantly more clear. The extra backtrace also isn't super nice.
SUPERCILEX commentedon Aug 18, 2023
A combination of those error messages would be great too.
RalfJung commentedon Aug 18, 2023
RalfJung commentedon Aug 18, 2023
I think the origin of the behavior change is #110975, and this is probably known, but maybe something can be done to improve the error.
Cc @Amanieu
Amanieu commentedon Aug 20, 2023
Currently the compiler does not differentiate between an unwind in a landing pad (recursive panic) and an unwind from a function that cannot unwind (
extern "C"
). It might be possible to handle these slightly differently so they produce different panic messages.RalfJung commentedon Aug 20, 2023
Well, unwind in a landing pad itself doesn't show that same error. It's the double-panic that triggers the error.
Here's the full error:
Having 2 stacktraces is already somewhat strange. And doesn't the panic machinery know that a panic-while-panicking occurred, so that it can print that?
Amanieu commentedon Aug 20, 2023
That's a
drop
called from normal execution, not from a landing pad. I was specifically referring to adrop
called from an unwind landing pad that is already being invoked as part of a previous unwind.The panic machinery can't determine that on its own, because this code is perfectly valid and shouldn't abort at the point of the inner panic, it should continue unwinding normally:
RalfJung commentedon Aug 20, 2023
Hm, I guess what happens is that the
drop
calls on the unwind path haveUnwindAction::Terminate
-- it's no longer the panic machinery that detects double-panic, it's the structure of the code itself. (EDIT: that's what you also just posted concurrently. :)So to fix that we'd probably need some sort of
reason
field onUnwindAction::Terminate
that records whether this is terminate-due-to-unwind-in-drop-on-cleanup-path or terminate-due-to-unwind-that-would-leave-extern "C"
.RalfJung commentedon Aug 20, 2023
And then the 2nd backtrace occurs because
panic_cannot_unwind
is the third panic in this program, and it runs intorust/library/std/src/panicking.rs
Lines 247 to 253 in d06ca0f
That's probably also undesirable for this case.
Amanieu commentedon Aug 20, 2023
There is some value in having a backtrace here since it shows you which function on the stack was no-unwind. But I agree that in practice this has rather limited value.
27 remaining items