我的应用程序需要通过标准输出将日志以JSON格式发送到fluentd。当我试图处理 panics 并将&std::panic::PanicInfo安排为std::panic::set_hook的JSON时,我无法找到从&PanicInfo检索 backtrace 的方法。有没有一种方法可以从自定义钩子中的panic中检索回溯?
&std::panic::PanicInfo
std::panic::set_hook
&PanicInfo
w7t8yxp51#
PanicInfo不包含回溯,但您可以在panic hook中自己捕获它。从set_hook文档:注册一个自定义的紧急挂接,替换以前注册的任何挂接。当线程发生异常时,在调用异常运行时之前,调用异常钩子。因此,钩子将在中止和展开运行时运行。默认钩子打印一条消息到标准错误,并在请求时生成一个回溯,但是这个行为可以用set_hook和take_hook函数来定制。由于panic hook会在解卷之前运行***,所以你可以使用@hellow已经提到的backtrace crate在panic hook中自己捕获回溯:
PanicInfo
set_hook
take_hook
backtrace
panic::set_hook(Box::new(|panic_info| { let backtrace = Backtrace::new(); // Do something with backtrace and panic_info. }));
oo7oh9g92#
您可以使用backtrace crate来生成当前堆栈的回溯。这与rust在内部使用RUST_BACKTRACE=1时发生panic时使用的crate完全相同。最简单的例子(取自文档)就是调用backtrace::Backtrace:
RUST_BACKTRACE=1
backtrace::Backtrace
use backtrace::Backtrace; fn main() { println!("{:?}", Backtrace::new()); }
我将返回(在我的示例中)
stack backtrace: 0: playground::main::h990b23e2761eee55 (0x564800753fb1) at src/main.rs:4 1: std::rt::lang_start::{{closure}}::hd025ca578a744b4f (0x564800753d3f) at /rustc/9fda7c2237db910e41d6a712e9a2139b352e558b/src/libstd/rt.rs:74 2: std::rt::lang_start_internal::{{closure}}::hdfc28107b5be47c9 (0x564800789f92) at src/libstd/rt.rs:59 std::panicking::try::do_call::h69790245ac2d03fe at src/libstd/panicking.rs:310 3: __rust_maybe_catch_panic (0x564800797409) at src/libpanic_unwind/lib.rs:102 4: std::panicking::try::h9c1cbc5599e1efbf (0x56480078a963) at src/libstd/panicking.rs:289 std::panic::catch_unwind::h0562757d03ff60b3 at src/libstd/panic.rs:398 std::rt::lang_start_internal::h540c897fe52ba9c5 at src/libstd/rt.rs:58 5: std::rt::lang_start::h78189d3d761bfa86 (0x564800753d18) at /rustc/9fda7c2237db910e41d6a712e9a2139b352e558b/src/libstd/rt.rs:74 6: main (0x5648007540b9) 7: __libc_start_main (0x7fdab1a23b96) 8: _start (0x564800753be9) 9: <unknown> (0x0)
xxls0lw83#
从Rust 1.65开始,你可以在稳定通道上使用std::backtrace::Backtrace,不需要外部crate:
std::backtrace::Backtrace
std::panic::set_hook(Box::new(|panic_info| { let backtrace = std::backtrace::Backtrace::capture(); eprintln!("My backtrace: {:#?}", backtrace); }));
3条答案
按热度按时间w7t8yxp51#
PanicInfo
不包含回溯,但您可以在panic hook中自己捕获它。从
set_hook
文档:注册一个自定义的紧急挂接,替换以前注册的任何挂接。
当线程发生异常时,在调用异常运行时之前,调用异常钩子。因此,钩子将在中止和展开运行时运行。默认钩子打印一条消息到标准错误,并在请求时生成一个回溯,但是这个行为可以用
set_hook
和take_hook
函数来定制。由于panic hook会在解卷之前运行***,所以你可以使用@hellow已经提到的
backtrace
crate在panic hook中自己捕获回溯:oo7oh9g92#
您可以使用backtrace crate来生成当前堆栈的回溯。
这与rust在内部使用
RUST_BACKTRACE=1
时发生panic时使用的crate完全相同。最简单的例子(取自文档)就是调用
backtrace::Backtrace
:我将返回(在我的示例中)
xxls0lw83#
从Rust 1.65开始,你可以在稳定通道上使用
std::backtrace::Backtrace
,不需要外部crate: