Created
February 15, 2019 12:41
-
-
Save therealprof/9b55e15eff37e626265a3af92698e940 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//! Writes panic messages to the beginning of RAM | |
//! | |
//! This crate contains an implementation of `panic_fmt` that logs panic messages to the beginning | |
//! of RAM, recklessly overwriting the previous contents of that area. After logging the message | |
//! the panic handler goes into an infinite loop, so a debugging probe can connect and pick up the | |
//! panic. | |
//! | |
//! Unlike other methods this allows to discover the panic reason post-mortem by attaching a | |
//! debugger probe after the device crashed. | |
//! | |
//! Currently this crate was only tested on ARM Cortex-M architecture but should be easily portable | |
//! to other platforms as required. | |
//! | |
//! # Usage | |
//! | |
//! ``` ignore | |
//! #![no_std] | |
//! | |
//! extern crate panic_ramdump; | |
//! | |
//! fn main() { | |
//! panic!("FOO") | |
//! } | |
//! ``` | |
//! | |
//! ``` text | |
//! (gdb) x/s 0x20000000 | |
//! 0x20000000: "panicked at 'FOO!', src/main.rs:6:5\n\276\244\001" | |
//! ``` | |
//! | |
#![allow(clippy::empty_loop)] | |
#![deny(missing_docs)] | |
#![deny(warnings)] | |
#![no_std] | |
use core::fmt::Write; | |
use core::panic::PanicInfo; | |
use cortex_m::interrupt; | |
struct Ram { | |
offset: u32, | |
} | |
/// Internal Write implementation to output the formatted panic string into RAM | |
impl core::fmt::Write for Ram { | |
fn write_str(&mut self, s: &str) -> Result<(), core::fmt::Error> { | |
// Obtain RAM start address from linker symbol _sbss | |
extern "C" { | |
static mut __sbss: u8; | |
} | |
let data = s.as_bytes(); | |
let len = data.len(); | |
unsafe { | |
core::ptr::copy( | |
data.as_ptr() as *mut u8, | |
(&mut __sbss as *mut u8).offset(self.offset as isize), | |
len, | |
) | |
}; | |
self.offset += len as u32; | |
Ok(()) | |
} | |
} | |
#[panic_handler] | |
fn panic(info: &PanicInfo) -> ! { | |
interrupt::disable(); | |
let mut ram = Ram { offset: 0 }; | |
#[cfg(feature = "light")] | |
{ | |
Ram::write_str(&mut ram, "panicked with '").ok(); | |
let cause = info | |
.payload() | |
.downcast_ref::<&'static str>() | |
.map(|s| *s) | |
.unwrap_or(&"<cause unknown>"); | |
Ram::write_str(&mut ram, cause).ok(); | |
Ram::write_str(&mut ram, "', ").ok(); | |
if let Some(location) = info.location() { | |
Ram::write_str(&mut ram, location.file()).ok(); | |
} | |
Ram::write_str(&mut ram, "\0").ok(); | |
} | |
#[cfg(not(feature = "light"))] | |
write!(ram, "{}\0", info).ok(); | |
loop {} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment