Abort on double panics

This commit is contained in:
Zhang Junyang
2024-08-06 02:32:08 +00:00
committed by Tate, Hongliang Tian
parent fe68b4b510
commit 05564ecd4f
3 changed files with 20 additions and 3 deletions

View File

@ -230,7 +230,7 @@ pub fn trace_panic_from_log(qemu_log: File, bin_path: PathBuf) {
.spawn() .spawn()
.unwrap(); .unwrap();
for line in lines.into_iter().rev() { 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:"); println!("[OSDK] The kernel seems panicked. Parsing stack trace for source lines:");
trace_exists = true; trace_exists = true;
} }

View File

@ -103,6 +103,7 @@ pub struct PanicInfo {
pub file: String, pub file: String,
pub line: usize, pub line: usize,
pub col: usize, pub col: usize,
pub resolve_panic: fn(),
} }
impl core::fmt::Display for PanicInfo { impl core::fmt::Display for PanicInfo {
@ -174,6 +175,7 @@ impl KtestItem {
Ok(()) => Err(KtestError::ShouldPanicButNoPanic), Ok(()) => Err(KtestError::ShouldPanicButNoPanic),
Err(e) => match e.downcast::<PanicInfo>() { Err(e) => match e.downcast::<PanicInfo>() {
Ok(s) => { Ok(s) => {
(s.resolve_panic)();
if let Some(expected) = self.should_panic.1 { if let Some(expected) = self.should_panic.1 {
if s.message == expected { if s.message == expected {
Ok(()) Ok(())

View File

@ -6,7 +6,7 @@ use core::ffi::c_void;
use crate::{ use crate::{
arch::qemu::{exit_qemu, QemuExitCode}, arch::qemu::{exit_qemu, QemuExitCode},
early_print, early_println, cpu_local_cell, early_print, early_println,
}; };
extern crate cfg_if; extern crate cfg_if;
@ -17,12 +17,24 @@ use unwinding::abi::{
_Unwind_GetGR, _Unwind_GetIP, _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 /// 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 /// 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 /// due to prismatic dependencies. That's why we export this symbol and state the
/// panic handler in the binary crate. /// panic handler in the binary crate.
#[export_name = "__aster_panic_handler"] #[export_name = "__aster_panic_handler"]
pub fn panic_handler(info: &core::panic::PanicInfo) -> ! { 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. // If in ktest, we would like to catch the panics and resume the test.
#[cfg(ktest)] #[cfg(ktest)]
{ {
@ -35,12 +47,15 @@ pub fn panic_handler(info: &core::panic::PanicInfo) -> ! {
file: info.location().unwrap().file().to_string(), file: info.location().unwrap().file().to_string(),
line: info.location().unwrap().line() as usize, line: info.location().unwrap().line() as usize,
col: info.location().unwrap().column() as usize, col: info.location().unwrap().column() as usize,
resolve_panic: || {
IN_PANIC.store(false);
},
}; };
// Throw an exception and expecting it to be caught. // Throw an exception and expecting it to be caught.
begin_panic(Box::new(throw_info.clone())); begin_panic(Box::new(throw_info.clone()));
} }
early_println!("{}", info); early_println!("{}", info);
early_println!("printing stack trace:"); early_println!("Printing stack trace:");
print_stack_trace(); print_stack_trace();
abort(); abort();
} }