panic_detector#
pw_kernel: Kernel experiments
panic_detector will scan a rust binary and through static analysis display a list of all panic call sites.
Currently only riscv32 elf files are supported.
Usage#
panic_detector can be integrated into the bazel build as follows:
1. Add panic handler#
Add a panic handler to the rust binary which will be used by panic_detector to find the panic call sites.
#[panic_handler]
fn panic_handler(info: &core::panic::PanicInfo) -> ! {
if let Some(location) = info.location() {
panic_is_possible(location.file().as_ptr(), location.file().len(), location.line(), location.column());
} else {
panic_is_possible(core::ptr::null(), 0, 0, 0);
}
}
#[no_mangle]
#[inline(never)]
extern "C" fn panic_is_possible(filename: *const u8, filename_len: usize, line: u32, col: u32) -> !{
// The arguments to this function are reverse-engineereddocs.html
// from the machine code by static analysis to
// display a list of all the panic call-sites to the
// user in the mutask_no_panic_test() error message.
// See welder/src/check_panic.rs for more details.
// If this symbol exists in the binary, panics are
// possible. Presubmit tests can ensure that this symbol
// does not exist in the final binary. Do not rename or
// remove this function.
core::hint::black_box(filename);
core::hint::black_box(filename_len);
core::hint::black_box(line);
core::hint::black_box(col);
loop {}
}
2. Add a test target#
Add a test target to bazel for the binary to validate.
rust_binary(
name = "example",
srcs = ["main.rs"],
)
load("//pw_kernel/tooling/panic_detector:rust_binary_no_panics_test.bzl", "rust_binary_no_panics_test")
rust_binary_no_panics_test(
name = "example_no_panic_test",
binary = ":example",
)
3. Run the bazel test#
If any panics are detected panic_detector will print the locations to stdout.
$ bazel test //:example_no_panic_test
<snip>
Found panic ufmt-0.2.0/src/helpers.rs line 58 column 13. Branch trace:
00103896 lui a0,0x104 (task0_entry)
0010389e jal ra,-1734 (task0_entry)
0010320a jalr ra,ra,-82 (panic_const_add_overflow)
001031d2 jalr ra,ra,-78 (core::panicking::panic_fmt)
00103192 jal ra,2 (rust_begin_unwind)
00103194 addi sp,sp,-16 (panic_is_possible)
<snip>