diff --git a/src/arch/x86_64/kernel/interrupts.rs b/src/arch/x86_64/kernel/interrupts.rs index af73c19b16..aa8047bf3a 100644 --- a/src/arch/x86_64/kernel/interrupts.rs +++ b/src/arch/x86_64/kernel/interrupts.rs @@ -373,17 +373,17 @@ impl IrqStatistics { } pub(crate) fn print_statistics() { - println!("Number of interrupts"); + panic_println!("Number of interrupts"); for (core_id, irg_statistics) in IRQ_COUNTERS.lock().iter() { for (i, counter) in irg_statistics.counters.iter().enumerate() { let counter = counter.load(Ordering::Relaxed); if counter > 0 { match get_irq_name(i.try_into().unwrap()) { Some(name) => { - println!("[{core_id}][{name}]: {counter}"); + panic_println!("[{core_id}][{name}]: {counter}"); } _ => { - println!("[{core_id}][{i}]: {counter}"); + panic_println!("[{core_id}][{i}]: {counter}"); } } } diff --git a/src/console.rs b/src/console.rs index 121cdf03a6..9818ebdaaa 100644 --- a/src/console.rs +++ b/src/console.rs @@ -1,4 +1,4 @@ -use core::fmt; +use core::{fmt, mem}; use hermit_sync::{InterruptTicketMutex, Lazy}; @@ -44,6 +44,14 @@ pub fn _print(args: fmt::Arguments<'_>) { CONSOLE.lock().write_fmt(args).unwrap(); } +#[doc(hidden)] +pub fn _panic_print(args: fmt::Arguments<'_>) { + use fmt::Write; + let mut console = unsafe { CONSOLE.make_guard_unchecked() }; + console.write_fmt(args).ok(); + mem::forget(console); +} + #[cfg(all(test, not(target_os = "none")))] mod tests { use super::*; diff --git a/src/lib.rs b/src/lib.rs index 796d2f8c07..b6824cff2b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -262,7 +262,7 @@ fn application_processor_main() -> ! { #[panic_handler] fn panic(info: &core::panic::PanicInfo<'_>) -> ! { let core_id = crate::arch::core_local::core_id(); - println!("[{core_id}][PANIC] {info}"); + panic_println!("[{core_id}][PANIC] {info}\n"); crate::scheduler::shutdown(1); } diff --git a/src/macros.rs b/src/macros.rs index b63426156d..871fc798f8 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -27,6 +27,26 @@ macro_rules! println { }}; } +/// Emergency output. +#[cfg(target_os = "none")] +#[macro_export] +macro_rules! panic_println { + () => {{ + $crate::console::_panic_print(::core::format_args!("\n")); + }}; + ($($arg:tt)*) => {{ + $crate::console::_panic_print(::core::format_args!("{}\n", format_args!($($arg)*))); + }}; +} + +#[cfg(not(target_os = "none"))] +#[macro_export] +macro_rules! panic_println { + ($($arg:tt)*) => { + println!($($arg)*); + }; +} + /// Prints and returns the value of a given expression for quick and dirty /// debugging. // Copied from std/macros.rs diff --git a/src/syscalls/interfaces/mod.rs b/src/syscalls/interfaces/mod.rs index 3afa06dfdc..b1154a9aaa 100644 --- a/src/syscalls/interfaces/mod.rs +++ b/src/syscalls/interfaces/mod.rs @@ -50,7 +50,7 @@ pub trait SyscallInterface: Send + Sync { fn shutdown(&self, error_code: i32) -> ! { // This is a stable message used for detecting exit codes for different hypervisors. - println!("exit status {error_code}"); + panic_println!("exit status {error_code}"); arch::processor::shutdown(error_code) }