-
Notifications
You must be signed in to change notification settings - Fork 13k
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: Mark allocation functions as nounwind #44049
Conversation
r? @BurntSushi (rust_highfive has picked a reviewer for you, use r? to override) |
This is perhaps best exemplified with this test which has no |
b04f587
to
021135c
Compare
Windows required unwind tables for all functions because anything can unwind due to an SEH exception. Does this PR make sure to not break that? |
That's |
src/liballoc/heap.rs
Outdated
@@ -27,36 +27,46 @@ pub mod __core { | |||
|
|||
extern "Rust" { | |||
#[allocator] | |||
#[allocator_nounwind] |
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.
Hmm, this is a new ungated attribute, right?
Since it's internal and the name doesn't matter much, rustc_allocator_nounwind
can be used instead, it'll be gated automatically.
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.
Sure yeah, I can change the name (currently this is just allowed under "custom_attributes")
src/liballoc/allocator.rs
Outdated
/// retain their validity until at least the instance of `Alloc` is dropped | ||
/// itself. | ||
/// | ||
/// * Implementations of `Alloc` are not currently memory safe if they 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.
Wait, I'm not clear on how to parse this. The way it reads now, I interpret this as saying that any implementation of Alloc
is not memory safe if it has a method that unwinds (panics), which AFAICT would even include the fn oom
method...
But if I'm understanding the change here correctly, the memory unsafety only arises for implementations that are installed as global allocators, right?
(Maybe we do need to make a unsafe trait GlobalAllocator: Allocator { }
just to track this extra-constraint on the implementations then...?)
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.
Note that if I am wrong, and that this somehow is relevant to all implementations of Alloc
, including ones that cannot be installed as global allocators, then I think more of the documentation for this trait needs to be revised.
E.g. text like this on fn alloc
implies that an implementor may panic (even if it is not recommended):
Implementations are encouraged to return
Err
on memory exhaustion rather than panicking or aborting, but this is not a strict requirement.
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.
Oh right yeah, I intended to make this specific to just global allocators
021135c
to
d37b501
Compare
Updated |
d37b501
to
956c2c0
Compare
src/liballoc/allocator.rs
Outdated
/// in the future, but currently an panic from any of these functions may lead | ||
/// to memory unsafety. Note that as of the time of this writing allocators | ||
/// *not* intending to be global allocators can still in their implementation | ||
/// without violating memory safety. |
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.
There's a word missing in this sentence: panic/unwind 😃
956c2c0
to
a4bfc4d
Compare
src/liballoc/allocator.rs
Outdated
/// itself. | ||
/// | ||
/// * Implementations of `Alloc` intended to be used for global allocators are | ||
/// not currently memory safe if they unwind. This restriction may be lifted |
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 would prefer "it's undefined behavior if a global allocator unwinds" to "not currently memory safe".
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.
"not memory safe" implies there's an edge case in which UB can happen, but allocators unwinding is always UB.
Beta-nominating again as this needs to be backported again. |
a4bfc4d
to
3947bd2
Compare
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 don't have a ton of context on the allocator stuff, so I'm probably not the best person to review this, but it LGTM.
src/liballoc/allocator.rs
Outdated
/// itself. | ||
/// | ||
/// * It's undefined behavior if global allocators unwind. This restriction may | ||
/// be lifted in the future, but currently an panic from any of these |
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.
s/an/a
This commit flags all allocation-related functions in liballoc as "this can't unwind" which should largely resolve the size-related issues found on rust-lang#42808. The documentation on the trait was updated with such a restriction (they can't panic) as well as some other words about the relative instability about implementing a bullet-proof allocator. Closes rust-lang#42808
3947bd2
to
b6f554b
Compare
@bors: r=BurntSushi |
📌 Commit b6f554b has been approved by |
std: Mark allocation functions as nounwind This commit flags all allocation-related functions in liballoc as "this can't unwind" which should largely resolve the size-related issues found on #42808. The documentation on the trait was updated with such a restriction (they can't panic) as well as some other words about the relative instability about implementing a bullet-proof allocator. Closes #42808
☀️ Test successful - status-appveyor, status-travis |
/// | ||
/// * Pointers returned from allocation functions must point to valid memory and | ||
/// retain their validity until at least the instance of `Alloc` is dropped | ||
/// itself. |
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.
This seems to imply that dealloc
doesn't make the pointer invalid, as it doesn't drop the Alloc
instance
This commit flags all allocation-related functions in liballoc as "this can't
unwind" which should largely resolve the size-related issues found on #42808.
The documentation on the trait was updated with such a restriction (they can't
panic) as well as some other words about the relative instability about
implementing a bullet-proof allocator.
Closes #42808