Rust-for-Linux/linux (original) (raw)

Documentation tests currently use kunit_do_failed_assertion which kills the current thread without unwinding the stack. This is UB in Rust as it deallocates the stack even if there may still be references to it. The first case where this can happen is in case of pinned stack variables. Pin requires that the value has it's Drop impl invoked before the memory is reused. This explicitly allows for example intrusive data structures. The second case is with scoped threads where child threads can reference variables on the stack of the parent thread. In this case the parent thread must wait for the completion of the child threads before returning from the current function. Exiting the current thread forcefully doesn't give the scoped thread implementation the chance of doing this. And finally there may be other unsafe code that temporarily puts references to variables on the stack of the current thread in global places. Yesterday me and @ojeda discussed in private how we should handle this. We came up with several options:

Keep aborting the current thread

This option is based on two observations:

We could make this option less likely to lead to crashes by avoiding pinning of stack variables.

Unwind the stack on test failures

In this option we would do panic!() in case of test failures and then unwind the stack. This option is free of any UB on the rust side and is the option how rust's builtin test framework works. The disadvantage of this option is that it requires adding a full DWARF unwinder in kernel space. Furthermore this depends on the currently unstable extern "C-unwind" abi to initiate the unwinding. It also gives some questions around how to handle unwinding past C kernel code.

Require all functions using the Kunit assertion macros to return TestResult<T>

In this option the macros would return Err(TestFailure) after reporting the failure allowing the failure to bubble up like a regular error. The advantage of this option is that it is simple to implement. The disadvantage is that it clutters the code a bit, which is not all that nice, especially for doctests.