panic runtime and C-unwind documentation#1226
Conversation
|
Hm... not sure how to fix the links to the newly-introduced page. Is there an index page I need to edit? Edit: I think I found it |
| | panic runtime | ABI | `panic`-unwind | Unforced foreign unwind | | ||
| | -------------- | ------------ | ------------------------------------- | ----------------------- | | ||
| | `panic=unwind` | `"C-unwind"` | unwind | unwind | | ||
| | `panic=unwind` | `"C"` | abort | UB | | ||
| | `panic=abort` | `"C-unwind"` | `panic!` aborts | abort | | ||
| | `panic=abort` | `"C"` | `panic!` aborts (no unwinding occurs) | UB | |
There was a problem hiding this comment.
| | panic runtime | ABI | `panic`-unwind | Unforced foreign unwind | | |
| | -------------- | ------------ | ------------------------------------- | ----------------------- | | |
| | `panic=unwind` | `"C-unwind"` | unwind | unwind | | |
| | `panic=unwind` | `"C"` | abort | UB | | |
| | `panic=abort` | `"C-unwind"` | `panic!` aborts | abort | | |
| | `panic=abort` | `"C"` | `panic!` aborts (no unwinding occurs) | UB | | |
| | panic runtime | ABI | `panic`-unwind | Unforced foreign unwind | | |
| | -------------- | ------------ | ------------------------------------- | ----------------------- | | |
| | `panic=unwind` | `"C-unwind"` | unwind | unwind | | |
| | `panic=unwind` | `"C"` | abort if unwinding reaches the function | UB if unwinding reaches the function | | |
| | `panic=abort` | `"C-unwind"` | aborts immediately (no unwinding occurs) | abort if unwinding reaches the function | | |
| | `panic=abort` | `"C"` | aborts immediately (no unwinding occurs) | UB if unwinding reaches the function | |
I found this a bit confusing. I believe there are subtle differences in terms of where the aborts occur and so forth. I have tried to clarify above, but I think it may be worth further clarifying.
It may also be worth adding some (perhaps non-normative) discussion of implementation:
- When compiling a function F with
panic=unwindandextern "C", the compiler inserts unwinding guards for Rust panics that trigger an abort when unwinding reaches F.
I am also be misunderstanding what's going on. I was a bit surprised to see "UB" for unforced-foreign-unwind with C=unwind. I guess that this table is combining two scenarios:
- what happens when you call a C++ function declared as extern "C", and it unwinds (UB, we haven't compiled any guards)
- what happens when an
extern "C"Rust function invokes some C++ function that throws (probably, in practice, an abort, but perhaps we have simplified to call it UB?)
Is that right?
There was a problem hiding this comment.
It's only UB for a foreign function declared as extern "C" to unwind.
There was a problem hiding this comment.
@nbdd0121 what happens when an extern "C" Rust function unwinds? I believe we insert an abort guard, but this table doesn't clarify that, right? Or maybe I don't understand what it's trying to convey. I'm imagining a scenario like
extern "C-unwind" fn throws();
extern "C" fn rust_fn() {
throws(); // unwinds
}In this case, I presume you get an abort -- and I think we guarantee that? But the way I read this table, it would be listed as UB.
There was a problem hiding this comment.
Hm....I don't know if the panic abort guard would currently catch and abort in that case, or if it relies on the personality function to only abort on true Rust panics. I agree that the behavior in the table as-written is UB.
There was a problem hiding this comment.
@nbdd0121 what happens when an
extern "C"Rust function unwinds? I believe we insert an abort guard, but this table doesn't clarify that, right? Or maybe I don't understand what it's trying to convey. I'm imagining a scenario likeextern "C-unwind" fn throws(); extern "C" fn rust_fn() { throws(); // unwinds }In this case, I presume you get an abort -- and I think we guarantee that? But the way I read this table, it would be listed as UB.
Unwinding out from extern "C" functions (defined in either Rust or foreign language) is UB.
In the case you listed, we insert guard to prevent unwinding from actually leaving a Rust extern "C" functions, therefore the function does not unwind, so UB is prevented; in this case we never unwinds out from a extern "C" Rust functions.
If you define a extern "C-unwind" Rust function and transmute it to extern "C" and then call it, it's not UB if unwinding does not happen, and it's UB if unwinding happens.
There was a problem hiding this comment.
@nikomatsakis With the change to the verbiage above, explaining that the table entries are specifically describing behavior at function boundaries, do you still want to make a change here?
There was a problem hiding this comment.
Please check whether the notes I suggested to add under the table are correct.
There was a problem hiding this comment.
@nikomatsakis Can I resolve this comment thread now?
|
Sorry for the delay; I think I've addressed all comments. |
|
@tmandry @nikomatsakis I'm not sure you saw my comments & changes last week, but I think this is ready for re-review. |
|
Could you squash the commits? |
|
@nbdd0121 Can that be done on merge? I've heard that GitHub sometimes has trouble with PR branches that receive force-pushes. |
|
I think I've resolved all open questions and concerns. Is there anything else needed from me at the moment? |
|
This really needs rebasing now. |
e8c62b4 to
6e83797
Compare
|
@nbdd0121 Done! |
|
@tmandry two changes since your review:
|
662b98d to
ffc056c
Compare
joshtriplett
left a comment
There was a problem hiding this comment.
I volunteered to review this on behalf of @rust-lang/lang.
I read through the entire PR in detail, and this looks good. It's entirely unsurprising, and it matches my understanding of how e.g. the unwind ABIs and panic strategies are supposed to work. I don't think anything here will be surprising to anyone on lang. This looks great, thank you for documenting it!
|
@rustbot labels -I-lang-nominated We discussed this on the lang call today briefly, but without reviewing the details. We discussed how probably it's the role of spec, or least of one of us on lang, to read it and flag anything that should be discussed. In general I think that's right, but looking at this again now, I'm thinking to myself that maybe we should in fact just FCP this sort of thing. It's hard to be really sure that nobody would flag anything here without having most people just read it. That said, let's not start that on this one. It's been outstanding long enough. It's the product of a ton of back and forth between @BatmanAoD, who pushed forward much of the underlying work (which did receive careful lang review), and @RalfJung, and then @ehuss has greatly polished it, and now it looks right on review to both @joshtriplett and myself, and an earlier draft was approved by @tmandry and reviewed by @nikomatsakis. So let's call this one good to go. @ehuss: There's an open thread with @BatmanAoD you might want to have a look at here, and then feel free to merge this at your discretion. |
|
I opened #1745 to follow up on the minor question I had about C++ unwinding. |
ehuss
left a comment
There was a problem hiding this comment.
Thank you @BatmanAoD for your patience. Sorry for letting this linger for so long. I appreciate all your help with this!
Tracking issue: rust-lang/rust#74990
Closes #579