Skip to content

Commit 3dde25e

Browse files
committed
Correct and expand documentation of handle_alloc_error and set_alloc_error_hook.
Add the following facts: * `handle_alloc_error` may panic instead of aborting. * What happens if a hook returns rather than diverging. * A hook may panic. (This was already demonstrated in an example, but not stated in prose.) * A hook must be sound to call — it cannot assume that it is only called by the runtime, since its function pointer can be retrieved by safe code.
1 parent b9177c0 commit 3dde25e

File tree

2 files changed

+39
-12
lines changed

2 files changed

+39
-12
lines changed

library/alloc/src/alloc.rs

+19-6
Original file line numberDiff line numberDiff line change
@@ -343,18 +343,31 @@ extern "Rust" {
343343
fn __rust_alloc_error_handler(size: usize, align: usize) -> !;
344344
}
345345

346-
/// Abort on memory allocation error or failure.
346+
/// Signal a memory allocation error.
347347
///
348-
/// Callers of memory allocation APIs wishing to abort computation
348+
/// Callers of memory allocation APIs wishing to cease execution
349349
/// in response to an allocation error are encouraged to call this function,
350-
/// rather than directly invoking `panic!` or similar.
350+
/// rather than directly invoking [`panic!`] or similar.
351351
///
352-
/// The default behavior of this function is to print a message to standard error
353-
/// and abort the process.
354-
/// It can be replaced with [`set_alloc_error_hook`] and [`take_alloc_error_hook`].
352+
/// This function is guaranteed to diverge (not return normally with a value), but depending on
353+
/// global configuration, it may either panic (resulting in unwinding or aborting as per
354+
/// configuration for all panics), or abort the process (with no unwinding).
355+
///
356+
/// The default behavior is:
357+
///
358+
/// * If the binary links against `std` (typically the case), then
359+
/// print a message to standard error and abort the process.
360+
/// This behavior can be replaced with [`set_alloc_error_hook`] and [`take_alloc_error_hook`].
361+
/// Future versions of Rust may panic by default instead.
362+
///
363+
/// * If the binary does not link against `std` (all of its crates are marked
364+
/// [`#![no_std]`][no_std]), then call [`panic!`] with a message.
365+
/// [The panic handler] applies as to any panic.
355366
///
356367
/// [`set_alloc_error_hook`]: ../../std/alloc/fn.set_alloc_error_hook.html
357368
/// [`take_alloc_error_hook`]: ../../std/alloc/fn.take_alloc_error_hook.html
369+
/// [The panic handler]: https://doc.rust-lang.org/reference/runtime.html#the-panic_handler-attribute
370+
/// [no_std]: https://doc.rust-lang.org/reference/names/preludes.html#the-no_std-attribute
358371
#[stable(feature = "global_alloc", since = "1.28.0")]
359372
#[rustc_const_unstable(feature = "const_alloc_error", issue = "92523")]
360373
#[cfg(all(not(no_global_oom_handling), not(test)))]

library/std/src/alloc.rs

+20-6
Original file line numberDiff line numberDiff line change
@@ -290,15 +290,29 @@ static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut());
290290

291291
/// Registers a custom allocation error hook, replacing any that was previously registered.
292292
///
293-
/// The allocation error hook is invoked when an infallible memory allocation fails, before
294-
/// the runtime aborts. The default hook prints a message to standard error,
295-
/// but this behavior can be customized with the [`set_alloc_error_hook`] and
296-
/// [`take_alloc_error_hook`] functions.
293+
/// The allocation error hook is invoked when an infallible memory allocation fails — that is,
294+
/// as a consequence of calling [`handle_alloc_error`] — before the runtime aborts.
297295
///
298-
/// The hook is provided with a `Layout` struct which contains information
296+
/// The allocation error hook is a global resource. [`take_alloc_error_hook`] may be used to
297+
/// retrieve a previously registered hook and wrap or discard it.
298+
///
299+
/// # What the provided `hook` function should expect
300+
///
301+
/// The hook function is provided with a [`Layout`] struct which contains information
299302
/// about the allocation that failed.
300303
///
301-
/// The allocation error hook is a global resource.
304+
/// The hook function may choose to panic or abort; in the event that it returns normally, this
305+
/// will cause an immediate abort.
306+
///
307+
/// Since [`take_alloc_error_hook`] is a safe function that allows retrieving the hook, the hook
308+
/// function must be _sound_ to call even if no memory allocations were attempted.
309+
///
310+
/// # The default hook
311+
///
312+
/// The default hook, used if [`set_alloc_error_hook`] is never called, prints a message to
313+
/// standard error (and then returns, causing the runtime to abort the process).
314+
/// Compiler options may cause it to panic instead, and the default behavior may be changed
315+
/// to panicking in future versions of Rust.
302316
///
303317
/// # Examples
304318
///

0 commit comments

Comments
 (0)