mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-08-02 20:08:31 +00:00
feat(core/rust): improved error reporting
This commit is contained in:
parent
e0bcdb16e0
commit
f9612898ab
@ -35,10 +35,12 @@ pub mod ui;
|
|||||||
fn panic_debug(panic_info: &core::panic::PanicInfo) -> ! {
|
fn panic_debug(panic_info: &core::panic::PanicInfo) -> ! {
|
||||||
// Filling at least the file and line information, if available.
|
// Filling at least the file and line information, if available.
|
||||||
// TODO: find out how to display message from panic_info.message()
|
// TODO: find out how to display message from panic_info.message()
|
||||||
|
|
||||||
if let Some(location) = panic_info.location() {
|
if let Some(location) = panic_info.location() {
|
||||||
trezorhal::common::__fatal_error("", "rs", location.file(), location.line(), "");
|
let file = location.file();
|
||||||
|
trezorhal::fatal_error::__fatal_error("", "rs", file, location.line(), "");
|
||||||
} else {
|
} else {
|
||||||
trezorhal::common::__fatal_error("", "rs", "", 0, "");
|
trezorhal::fatal_error::__fatal_error("", "rs", "", 0, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +58,7 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
|
|||||||
// raises a Hard Fault on hardware.
|
// raises a Hard Fault on hardware.
|
||||||
//
|
//
|
||||||
// Otherwise, use `unwrap!` macro from trezorhal.
|
// Otherwise, use `unwrap!` macro from trezorhal.
|
||||||
trezorhal::common::__fatal_error("", "rs", "", 0, "");
|
fatal_error!("", "rs");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_arch = "arm"))]
|
#[cfg(not(target_arch = "arm"))]
|
||||||
|
@ -1,100 +0,0 @@
|
|||||||
mod ffi {
|
|
||||||
extern "C" {
|
|
||||||
// trezorhal/common.c
|
|
||||||
pub fn __fatal_error(
|
|
||||||
expr: *const cty::c_char,
|
|
||||||
msg: *const cty::c_char,
|
|
||||||
file: *const cty::c_char,
|
|
||||||
line: i32,
|
|
||||||
func: *const cty::c_char,
|
|
||||||
) -> !;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn __fatal_error(expr: &str, msg: &str, file: &str, line: u32, func: &str) -> ! {
|
|
||||||
const MAX_LEN: usize = 50 + 1; // Leave space for the null terminator.
|
|
||||||
|
|
||||||
fn as_cstr_buf(s: &str) -> [cty::c_char; MAX_LEN] {
|
|
||||||
let mut buf = [0 as cty::c_char; MAX_LEN];
|
|
||||||
for (i, c) in s.as_bytes().iter().enumerate() {
|
|
||||||
if i >= MAX_LEN {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
buf[i] = *c as cty::c_char;
|
|
||||||
}
|
|
||||||
buf[MAX_LEN - 1] = 0;
|
|
||||||
buf
|
|
||||||
}
|
|
||||||
|
|
||||||
let expr_buf = as_cstr_buf(expr);
|
|
||||||
let msg_buf = as_cstr_buf(msg);
|
|
||||||
let file_buf = as_cstr_buf(file);
|
|
||||||
let func_buf = as_cstr_buf(func);
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
ffi::__fatal_error(
|
|
||||||
expr_buf.as_ptr(),
|
|
||||||
msg_buf.as_ptr(),
|
|
||||||
file_buf.as_ptr(),
|
|
||||||
line as i32,
|
|
||||||
func_buf.as_ptr(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait UnwrapOrFatalError<T> {
|
|
||||||
fn unwrap_or_fatal_error(self, expr: &str, msg: &str, file: &str, line: u32, func: &str) -> T;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> UnwrapOrFatalError<T> for Option<T> {
|
|
||||||
fn unwrap_or_fatal_error(self, expr: &str, msg: &str, file: &str, line: u32, func: &str) -> T {
|
|
||||||
match self {
|
|
||||||
Some(x) => x,
|
|
||||||
None => __fatal_error(expr, msg, file, line, func),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, E> UnwrapOrFatalError<T> for Result<T, E> {
|
|
||||||
fn unwrap_or_fatal_error(self, expr: &str, msg: &str, file: &str, line: u32, func: &str) -> T {
|
|
||||||
match self {
|
|
||||||
Ok(x) => x,
|
|
||||||
Err(_) => __fatal_error(expr, msg, file, line, func),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! function_name {
|
|
||||||
() => {{
|
|
||||||
fn f() {}
|
|
||||||
fn type_name_of<T>(_: T) -> &'static str {
|
|
||||||
core::any::type_name::<T>()
|
|
||||||
}
|
|
||||||
let name = type_name_of(f);
|
|
||||||
name.get(..name.len() - 3).unwrap_or("")
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! unwrap {
|
|
||||||
($e:expr, $msg:expr) => {{
|
|
||||||
use crate::trezorhal::common::UnwrapOrFatalError;
|
|
||||||
$e.unwrap_or_fatal_error("unwrap failed", $msg, file!(), line!(), function_name!())
|
|
||||||
}};
|
|
||||||
($expr:expr) => {
|
|
||||||
unwrap!($expr, "")
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! ensure {
|
|
||||||
($what:expr, $error:expr) => {
|
|
||||||
if !($what) {
|
|
||||||
fatal_error!(stringify!($what), $error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! fatal_error {
|
|
||||||
($expr:expr, $msg:expr) => {{
|
|
||||||
crate::trezorhal::common::__fatal_error($expr, $msg, file!(), line!(), function_name!());
|
|
||||||
}};
|
|
||||||
}
|
|
108
core/embed/rust/src/trezorhal/fatal_error.rs
Normal file
108
core/embed/rust/src/trezorhal/fatal_error.rs
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
mod ffi {
|
||||||
|
extern "C" {
|
||||||
|
// trezorhal/common.c
|
||||||
|
pub fn shutdown() -> !;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
use crate::ui::screens::screen_fatal_error;
|
||||||
|
#[cfg(not(feature = "bootloader"))]
|
||||||
|
use heapless::String;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "bootloader"))]
|
||||||
|
use crate::ui::util::u32_to_str;
|
||||||
|
|
||||||
|
fn shutdown() -> ! {
|
||||||
|
unsafe { ffi::shutdown() }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "bootloader")]
|
||||||
|
pub fn __fatal_error(_expr: &str, _msg: &str, _file: &str, _line: u32, _func: &str) -> ! {
|
||||||
|
screen_fatal_error(Some("BL.rs"), "BL.rs");
|
||||||
|
shutdown()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "bootloader"))]
|
||||||
|
pub fn __fatal_error(_expr: &str, msg: &str, file: &str, line: u32, _func: &str) -> ! {
|
||||||
|
let mut buf: String<256> = String::new();
|
||||||
|
let _ = buf.push_str(file); // Nothing we can do if this fails
|
||||||
|
let _ = buf.push_str(": ");
|
||||||
|
|
||||||
|
let mut line_buf = [0u8; 10];
|
||||||
|
if let Some(text) = u32_to_str(line, &mut line_buf) {
|
||||||
|
let _ = buf.push_str(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
screen_fatal_error(Some(msg), buf.as_str());
|
||||||
|
shutdown()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait UnwrapOrFatalError<T> {
|
||||||
|
fn unwrap_or_fatal_error(self, expr: &str, msg: &str, file: &str, line: u32, func: &str) -> T;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> UnwrapOrFatalError<T> for Option<T> {
|
||||||
|
fn unwrap_or_fatal_error(self, expr: &str, msg: &str, file: &str, line: u32, func: &str) -> T {
|
||||||
|
match self {
|
||||||
|
Some(x) => x,
|
||||||
|
None => __fatal_error(expr, msg, file, line, func),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, E> UnwrapOrFatalError<T> for Result<T, E> {
|
||||||
|
fn unwrap_or_fatal_error(self, expr: &str, msg: &str, file: &str, line: u32, func: &str) -> T {
|
||||||
|
match self {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(_) => __fatal_error(expr, msg, file, line, func),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! function_name {
|
||||||
|
() => {{
|
||||||
|
#[cfg(not(feature = "bootloader"))]
|
||||||
|
{
|
||||||
|
fn f() {}
|
||||||
|
fn type_name_of<T>(_: T) -> &'static str {
|
||||||
|
core::any::type_name::<T>()
|
||||||
|
}
|
||||||
|
let name = type_name_of(f);
|
||||||
|
name.get(..name.len() - 3).unwrap_or("")
|
||||||
|
}
|
||||||
|
#[cfg(feature = "bootloader")]
|
||||||
|
{
|
||||||
|
""
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! unwrap {
|
||||||
|
($e:expr, $msg:expr) => {{
|
||||||
|
use crate::trezorhal::fatal_error::UnwrapOrFatalError;
|
||||||
|
$e.unwrap_or_fatal_error(stringify!($e), $msg, file!(), line!(), function_name!())
|
||||||
|
}};
|
||||||
|
($expr:expr) => {
|
||||||
|
unwrap!($expr, "unwrap failed")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! ensure {
|
||||||
|
($what:expr, $error:expr) => {
|
||||||
|
if !($what) {
|
||||||
|
fatal_error!(stringify!($what), $error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! fatal_error {
|
||||||
|
($expr:expr, $msg:expr) => {{
|
||||||
|
crate::trezorhal::fatal_error::__fatal_error(
|
||||||
|
stringify!($expr),
|
||||||
|
$msg,
|
||||||
|
file!(),
|
||||||
|
line!(),
|
||||||
|
function_name!(),
|
||||||
|
);
|
||||||
|
}};
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
pub mod bip39;
|
pub mod bip39;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
#[allow(unused_macros)]
|
#[allow(unused_macros)]
|
||||||
pub mod common;
|
pub mod fatal_error;
|
||||||
#[cfg(feature = "ui")]
|
#[cfg(feature = "ui")]
|
||||||
pub mod display;
|
pub mod display;
|
||||||
#[cfg(feature = "dma2d")]
|
#[cfg(feature = "dma2d")]
|
||||||
|
Loading…
Reference in New Issue
Block a user