From f3c3bd738413cd201ea58ac9834b261399037be6 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Thu, 2 Jul 2020 13:10:11 +0800 Subject: [PATCH] Backtrace: panic handler with proper backtrace. --- src/libunwind/build.rs | 1 + src/runtime/src/main.rs | 3 +++ src/runtime/src/panic.rs | 26 ++++++++++++++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 src/runtime/src/panic.rs diff --git a/src/libunwind/build.rs b/src/libunwind/build.rs index d38a8854..d7f6645d 100644 --- a/src/libunwind/build.rs +++ b/src/libunwind/build.rs @@ -39,6 +39,7 @@ mod llvm_libunwind { let cfg = &mut cc::Build::new(); setup_options(cfg); cfg.compiler("clang"); + cfg.flag("-funwind-tables"); let unwind_sources = vec![ "Unwind-sjlj.c", diff --git a/src/runtime/src/main.rs b/src/runtime/src/main.rs index 21402a9e..2ec3e577 100644 --- a/src/runtime/src/main.rs +++ b/src/runtime/src/main.rs @@ -2,6 +2,8 @@ #![no_main] #![recursion_limit="1024"] // for futures_util::select! #![feature(llvm_asm)] +#![feature(alloc_error_handler)] +#![feature(panic_info_message)] extern crate alloc; @@ -24,6 +26,7 @@ mod kernel; mod moninj; mod load_pl; mod eh_artiq; +mod panic; fn identifier_read(buf: &mut [u8]) -> &str { unsafe { diff --git a/src/runtime/src/panic.rs b/src/runtime/src/panic.rs new file mode 100644 index 00000000..b49ba562 --- /dev/null +++ b/src/runtime/src/panic.rs @@ -0,0 +1,26 @@ +use libboard_zynq::{slcr, print, println}; +use unwind::backtrace; + +#[panic_handler] +fn panic(info: &core::panic::PanicInfo) -> ! { + print!("panic at "); + if let Some(location) = info.location() { + print!("{}:{}:{}", location.file(), location.line(), location.column()); + } else { + print!("unknown location"); + } + if let Some(message) = info.message() { + println!(": {}", message); + } else { + println!(""); + } + println!("Backtrace: "); + let _ = backtrace(|ip| { + // Backtrace gives us the return address, i.e. the address after the delay slot, + // but we're interested in the call instruction. + println!("{:#08x}", ip - 2 * 4); + }); + println!("End backtrace"); + slcr::RegisterBlock::unlocked(|slcr| slcr.soft_reset()); + loop {} +}