-
Notifications
You must be signed in to change notification settings - Fork 505
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
panic runtime and C-unwind documentation #1226
base: master
Are you sure you want to change the base?
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 |
src/items/functions.md
Outdated
| 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| 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=unwind
andextern "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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's only UB for a foreign function declared as extern "C"
to unwind.
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.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 panic
s. I agree that the behavior in the table as-written is UB.
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.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check whether the notes I suggested to add under the table are correct.
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.
@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:
|
Co-authored-by: Daira-Emma Hopwood <[email protected]>
…or execution out of a note
Co-authored-by: Ralf Jung <[email protected]>
We don't document rustc lints as language rules. I think in this case, it's fine to mention it, but it should just be in a note block.
I believe this is what was intended.
This should probably be reworked in the future so the ABI chapter owns this information. But for now, it doesn't really say anything useful.
This is to make it clear that the unwind is going *past* it, not just into it.
We generally don't document old behavior in the reference.
This is intended since there are multiple ways to suppress a destructor.
Per the style guide, lines should not be wrapped.
4e05720
to
c63cdbc
Compare
The intent here is to introduce higher-level concepts first, and then go into the details of unwinding.
This is intended to clearly define two concepts, the runtime versus the strategy. Although there is significant overlap between them (they are chosen using the same CLI flag after all), I think it is helpful to define them as separate concepts.
I felt like this sentence is making an over-bold statement. There are ways to violate the assumptions of the Rust runtime using Rust code. Usually that is only with `unsafe` code that is otherwise violating requirements, though there may still be some holes where it can be done in safe code (hopefully those holes continue to be plugged). I feel more comfortable without this, since the primary sentence (don't violate the runtime!) is enough on its own.
Tracking issue: rust-lang/rust#74990
Closes #579