Skip to content

unwind safety fixes#140

Open
Mirko-A wants to merge 3 commits intoRust-for-Linux:mainfrom
Mirko-A:mirko/fix-unwind-safety-bug
Open

unwind safety fixes#140
Mirko-A wants to merge 3 commits intoRust-for-Linux:mainfrom
Mirko-A:mirko/fix-unwind-safety-bug

Conversation

@Mirko-A
Copy link
Copy Markdown

@Mirko-A Mirko-A commented Apr 27, 2026

Adds unwind-safety fixes to in-place initialization helpers so partially initialized values are dropped on both errors and panics. Changes:

  • Add __internal::ArrayInitGuard type that safely initializes an array by running an initializer on each element, keeping track of the number of initialized elements. When dropped, the guard drops the already-initialized portion of the array. Use the guard in [pin_]init_array_from_fn; mem::forget it on success.
  • Use __internal::DropGuard in [pin_]chain so a panic/error in the chained closure drops the value initialized in the first stage; mem::forget the guard on success.
  • Add regression tests.

Closes: #136


The approach taken here was suggested in the issue itself, thus I added a Suggested-by tag. I hope that is okay.

Mirko-A added 3 commits April 27, 2026 20:49
Adds a guard type that safely initializes an array by running an initializer
on each element, keeping track of the number of initialized elements. In the
case of a panic or error in the per-element initializer, the guard drops the
already-initialized portion of the array; `mem::forget` the guard on success.

The previous code only ran cleanup on the explicit error path. If the per-
element initializer panicked partway through, the elements already written
into the array would be leaked: their `Drop` impls would never run.

Link: Rust-for-Linux#136
Reported-by: Gary Guo <gary@garyguo.net>
Suggested-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Mirko Adzic <adzicmirko97@gmail.com>
Adds a drop guard before the call to the chained closure so that the
value initialized by the first stage is dropped if the closure errors
or panics; `mem::forget` the guard on success.

The previous code only ran cleanup on the explicit error path, leaking
the first-stage value if the chained closure panicked.

Link: Rust-for-Linux#136
Reported-by: Gary Guo <gary@garyguo.net>
Suggested-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Mirko Adzic <adzicmirko97@gmail.com>
Cover both fixes added in the series:

- `[pin_]init_array_from_fn`: a panic or error from element `i`'s
  initializer drops the previously initialized elements `0..i`.
- `[pin_]chain`: a panic or error from the chained closure drops
  the value initialized by the first stage.

Also assert no double-drop on the success paths.

Signed-off-by: Mirko Adzic <adzicmirko97@gmail.com>
@Mirko-A Mirko-A force-pushed the mirko/fix-unwind-safety-bug branch from 235fcfb to 45e29c0 Compare April 27, 2026 19:38
@Mirko-A Mirko-A marked this pull request as ready for review April 27, 2026 20:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

pin_init_array_from_fn and pin_chain are not unwind-safe

1 participant