diff --git a/osdk/src/util.rs b/osdk/src/util.rs index 2d629aa63..0ff06dc44 100644 --- a/osdk/src/util.rs +++ b/osdk/src/util.rs @@ -230,7 +230,7 @@ pub fn trace_panic_from_log(qemu_log: File, bin_path: PathBuf) { .spawn() .unwrap(); for line in lines.into_iter().rev() { - if line.contains("printing stack trace:") { + if line.contains("Printing stack trace:") { println!("[OSDK] The kernel seems panicked. Parsing stack trace for source lines:"); trace_exists = true; } diff --git a/ostd/libs/ostd-test/src/lib.rs b/ostd/libs/ostd-test/src/lib.rs index 94e2207f1..3ec04c608 100644 --- a/ostd/libs/ostd-test/src/lib.rs +++ b/ostd/libs/ostd-test/src/lib.rs @@ -103,6 +103,7 @@ pub struct PanicInfo { pub file: String, pub line: usize, pub col: usize, + pub resolve_panic: fn(), } impl core::fmt::Display for PanicInfo { @@ -174,6 +175,7 @@ impl KtestItem { Ok(()) => Err(KtestError::ShouldPanicButNoPanic), Err(e) => match e.downcast::() { Ok(s) => { + (s.resolve_panic)(); if let Some(expected) = self.should_panic.1 { if s.message == expected { Ok(()) diff --git a/ostd/src/panicking.rs b/ostd/src/panicking.rs index 54d3de1e8..c82bcab4d 100644 --- a/ostd/src/panicking.rs +++ b/ostd/src/panicking.rs @@ -6,7 +6,7 @@ use core::ffi::c_void; use crate::{ arch::qemu::{exit_qemu, QemuExitCode}, - early_print, early_println, + cpu_local_cell, early_print, early_println, }; extern crate cfg_if; @@ -17,12 +17,24 @@ use unwinding::abi::{ _Unwind_GetGR, _Unwind_GetIP, }; +cpu_local_cell! { + static IN_PANIC: bool = false; +} + /// The panic handler must be defined in the binary crate or in the crate that the binary /// crate explicity declares by `extern crate`. We cannot let the base crate depend on OSTD /// due to prismatic dependencies. That's why we export this symbol and state the /// panic handler in the binary crate. #[export_name = "__aster_panic_handler"] pub fn panic_handler(info: &core::panic::PanicInfo) -> ! { + let _irq_guard = crate::trap::disable_local(); + + if IN_PANIC.load() { + early_println!("{}", info); + early_println!("The panic handler panicked when processing the above panic. Aborting."); + abort(); + } + // If in ktest, we would like to catch the panics and resume the test. #[cfg(ktest)] { @@ -35,12 +47,15 @@ pub fn panic_handler(info: &core::panic::PanicInfo) -> ! { file: info.location().unwrap().file().to_string(), line: info.location().unwrap().line() as usize, col: info.location().unwrap().column() as usize, + resolve_panic: || { + IN_PANIC.store(false); + }, }; // Throw an exception and expecting it to be caught. begin_panic(Box::new(throw_info.clone())); } early_println!("{}", info); - early_println!("printing stack trace:"); + early_println!("Printing stack trace:"); print_stack_trace(); abort(); }