Rust捕獲全局panic并記錄進程退出日志的方法
本文提供了捕獲全局panic
并記錄進程退出日志的方法。
1. 使用 panic::set_hook 注冊異常處理
use human_panic::setup_panic; use log::error; use std::{boxed::Box, panic}; fn hook(panic_info: &panic::PanicInfo) { if cfg!(debug_assertions) { let err_message = format!("panic occurred {:?}", panic_info); error!("{}", err_message); } else { let err_message = match panic_info.payload().downcast_ref::<&str>() { Option::Some(&str) => { let err_message = format!( "panic info: {:?}, occurred in {:?}", str, panic_info.location() ); err_message } Option::None => { let err_message = format!("panic occurred in {:?}", panic_info.location()); err_message } }; error!("{}", err_message); } } /// 注冊異常處理函數(shù) /// 在panic發(fā)出后,在panic運行時之前,觸發(fā)鉤子函數(shù)去處理這個panic信息。 /// panic信息被保存在PanicInfo結構體中。 pub fn register_panic_hook() { panic::set_hook(Box::new(|panic_info| { hook(panic_info); })); // setup_panic!(); }
2. panic 觸發(fā)異常
use core_utils::panic::register_panic_hook; use core_utils::panic::register_panic_hook; use env_logger; use log::LevelFilter; use std::thread; use std::time::Duration; #[test] fn test_panic_set_hook() { let _ = env_logger::builder() .is_test(true) .filter(None, LevelFilter::Debug) .try_init(); register_panic_hook(); thread::spawn(|| { panic!("child thread panic"); }); thread::sleep(Duration::from_millis(100)); }
日志如下
debug模式
[2024-04-20T05:32:30Z ERROR core_utils::panic] panic occurred PanicInfo { payload: Any { .. }, message: Some(child thread panic), location: Location { file: "core_utils/tests/test_panic.rs", line: 16, col: 9 }, can_unwind: true, force_no_backtrace: false }
release模式
[2024-04-20T05:41:06Z ERROR core_utils::panic] panic info: "child thread panic", occurred in Some(Location { file: "core_utils/tests/test_panic.rs", line: 17, col: 9 })
3. unwrap 觸發(fā)異常
#[test] fn test_panic_unwrap() { let _ = env_logger::builder() .is_test(true) .filter(None, LevelFilter::Debug) .try_init(); register_panic_hook(); thread::spawn(|| { let _ = "abc".parse::<i32>().unwrap(); }); thread::sleep(Duration::from_millis(100)); }
日志如下
debug模式
[2024-04-20T05:38:22Z ERROR core_utils::panic] panic occurred PanicInfo { payload: Any { .. }, message: Some(called `Result::unwrap()` on an `Err` value: ParseIntError { kind: InvalidDigit }), location: Location { file: "core_utils/tests/test_panic.rs", line: 33, col: 38 }, can_unwind: true, force_no_backtrace: false }
release模式
注意:unwrap觸發(fā)的異常會導致 panic_info.payload().downcast_ref::<&str>()
返回結果為 None
[2024-04-20T05:42:34Z ERROR core_utils::panic] panic occurred in Some(Location { file: "core_utils/tests/test_panic.rs", line: 33, col: 38 })
4. 使用 human_panic
human_panic
只能在非debug模式且環(huán)境變量RUST_BACKTRACE
未設置的情況下才會生效。
注冊 hook
use human_panic::setup_panic; pub fn register_panic_hook() { setup_panic!(); }
模擬release環(huán)境異常
use core_utils::panic::register_panic_hook; use env_logger; use human_panic::setup_panic; use log::error; use std::thread; use std::time::Duration; fn main() { env_logger::init(); register_panic_hook(); thread::spawn(|| { panic!("error"); // let _ = "abc".parse::<i32>().unwrap(); }); thread::sleep(Duration::from_secs(1)); }
cargo run --bin human_panic --release
panic
發(fā)生時會在在臨時文件夾下面創(chuàng)建一個報告文件
Well, this is embarrassing. core_utils had a problem and crashed. To help us diagnose the problem you can send us a crash report. We have generated a report file at "/var/folders/gx/hn6l2rd56cx0lcwnkblxqvmr0000gn/T/report-93547ab5-9341-4212-a9af-6d2f17d6311d.toml". Submit an issue or email with the subject of "core_utils Crash Report" and include the report as an attachment. We take privacy seriously, and do not perform any automated error collection. In order to improve the software, we rely on people to submit reports. Thank you kindly!
報告內(nèi)容如下
"name" = "core_utils" "operating_system" = "Mac OS 14.1.1 [64-bit]" "crate_version" = "0.1.0" "explanation" = """ Panic occurred in file 'core_utils/src/bin/human_panic.rs' at line 14 """ "cause" = "error" "method" = "Panic" "backtrace" = """ 0: 0x105b840a5 - core::panicking::panic_fmt::h2aac8cf45f7ae617 1: 0x1059fd7c6 - std::sys_common::backtrace::__rust_begin_short_backtrace::h4bae865db206eae3 2: 0x1059fe2fd - core::ops::function::FnOnce::call_once{{vtable.shim}}::ha8d441119e8b7a5a 3: 0x105b5a819 - std::sys::pal::unix::thread::Thread::new::thread_start::h679ffa03f8a73496 4: 0x7ff801993202 - __pthread_start"""
到此這篇關于Rust捕獲全局panic并記錄進程退出日志的文章就介紹到這了,更多相關rust 捕獲全局panic內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
關于Rust?使用?dotenv?來設置環(huán)境變量的問題
在項目中,我們通常需要設置一些環(huán)境變量,用來保存一些憑證或其它數(shù)據(jù),這時我們可以使用dotenv這個crate,接下來通過本文給大家介紹Rust?使用dotenv來設置環(huán)境變量的問題,感興趣的朋友一起看看吧2022-01-01Rust?Atomics?and?Locks內(nèi)存序Memory?Ordering詳解
這篇文章主要為大家介紹了Rust?Atomics?and?Locks內(nèi)存序Memory?Ordering詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-02-02Rust Atomics and Locks并發(fā)基礎理解
這篇文章主要為大家介紹了Rust Atomics and Locks并發(fā)基礎理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-02-02Rust調用函數(shù)操作符?.?和?::?的區(qū)別詳解
在Rust中,.和::操作符都可以用來調用方法,但它們的用法有所不同,所以本文就將詳細的給大家介紹一下.和::操作符的區(qū)別,感興趣的同學跟著小編一起來學習吧2023-07-07vscode搭建rust開發(fā)環(huán)境的圖文教程
本文主要介紹了vscode搭建rust開發(fā)環(huán)境的圖文教程,文中通過圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-08-08