TL;DR: I'm looking for ways to approximate asynchronous unwind tables by changing MIR to force the generation of cleanup routines even when no Rust-level panic is possible.
As part of a large research OS project, I have implemented custom unwinding support for our no_std
environment that works correctly for all explicit language-level panic
s, i.e. synchronous unwinding. However, when trying to start unwinding from any other non-panicking part of the code (for example, after a machine fault), there is no unwinding landing pad that covers those instruction pointers, which is expected.
The full-fledged correct solution for this is asynchronous unwind tables, which Rust does not support due to LLVM lacking support for it.
Thus, I'm looking for help with an alternate solution: changing the compiler to generate unwind cleanup routines / landing pads for all basic blocks, statements, or even instructions as an attempt to approximate true asynchronous unwinding. This is my first foray into rustc itself so I'm no expert, but so far I have looked into MIR because it appears to be where cleanup routines are handled, such as the no-landing-pads
pass.
Here's a code example illustrating the problem:
fn foo() {
let _b = Box::new(5);
// Here, unwinding is started via an out-of-band mechanism,
// but the `_b` Box will not be cleaned up/dropped
// because no panic is possible in `foo()`.
}
fn main() {
let _a = Box::new(10);
foo();
// Because `foo()` is a `Call`,
// the `_a` box will be cleaned up as expected.
}
My first naive attempt was to modify librustc_mir::build::scope::Scopes::may_panic()
to always return true
, but that was insufficient because the terminator for foo
did not have any need for cleanup to begin with. I have played around with mir::build
and mir::scope
for a while, to no avail.
I believe a potential solution is to change the TerminatorKind
of each block such that it includes an unwind cleanup
element, but I am not sure how Terminator
s are actually created in the first place nor how or to what kind I should change that terminator to maintain correctness.
I would greatly appreciate any tips on getting started or ideas on what other approaches to try.
=====
Thanks, and apologies if this is the wrong forum; I understand this is a wild idea but was still hoping to get in contact with people that work on drop
s per the Rustc experts map, such as @arielb1 or anyone else knowledgeable about unwinding.