Skip to main content

Module fallible

Module fallible 

Source
Expand description

Fallible heap allocation for entity-creation paths (issue 1551, defect 2).

§Why this exists

Box::new cannot fail: when the global allocator returns NULL it calls alloc::alloc::handle_alloc_error, and in a std build that runs libstd’s default_alloc_error_hook, which writes "memory allocation of N bytes failed" to fd 2 before aborting.

On a Zephyr native_sim image fd 2 is the POSIX fdtable’s stdinout entry, whose write re-enters zvfs_write forever (issue 0589). So the message never appears: the thread overflows its stack inside a recursive k_mutex and the process dies with SIGSEGV (exit 139). Measured on the derived-tiers-cpp image, ~104,735 frames deep, from a Box::new in the RMW adapter whose C caller had a perfectly good error return.

None of the three levers that would make the OOM handler itself safe are available on the pinned stable toolchain (measured on rustc 1.98.1): std::alloc::set_alloc_error_hook (feature alloc_error_hook), #[alloc_error_handler] (feature alloc_error_handler) and -Zoom=panic are all nightly-only, and a GlobalAlloc cannot tell a fallible caller from an infallible one, so the allocator cannot halt on the caller’s behalf without also breaking every try_reserve. The remaining lever is at the CALL SITE: an allocation whose failure the caller can report must not go through the infallible API at all.

§The rule

On a path that creates an entity (session, publisher, subscription, service, client, event registration) AND already has an error return to a C/C++ caller, allocate through try_box and map Err to the caller’s out-of-memory code (NROS_RMW_RET_BAD_ALLOC / crate::TransportError::BadAlloc). Box::try_new is the std spelling and is unstable; this is its stable equivalent, and the one spelling in the tree.

Functions§

try_box
Move value into a new heap allocation, or hand it back if the global allocator is exhausted.
try_box_uninit
An UNINITIALISED heap allocation for one T, or None if the global allocator is exhausted.
try_zeroed_bytes
A zeroed len-byte heap buffer, or None if the allocator is exhausted.