在Rust的钩子中从恐慌中检索回溯?

问题描述 投票:2回答:2

我的应用程序需要通过stdout将日志发送为流畅的JSON格式。 当我试图处理恐慌并用&std::panic::PanicInfo安排std::panic::set_hook作为JSON时,我找不到从&PanicInfo检索回溯的方法。

有没有办法从自定义钩子中的恐慌中检索回溯?

logging rust backtrace panic
2个回答
4
投票

PanicInfo不包含回溯,但你可以在恐慌钩子中捕获它。

来自set_hook文档:

注册一个自定义的恐慌钩子,替换之前注册的任何一个。

当线程发生混乱时,但在调用恐慌运行时之前调用恐慌钩子。因此,钩子将与中止和退绕运行时一起运行。默认钩子将消息打印到标准错误并在请求时生成回溯,但可以使用set_hooktake_hook函数自定义此行为。

由于恐慌钩在展开之前运行,你可以使用@hellow已经提到的backtrace箱子在恐慌钩子中自己捕捉回溯:

panic::set_hook(Box::new(|panic_info| {
    let backtrace = Backtrace::new();
    //  Do something with backtrace and panic_info.
}));

2
投票

您可以使用backtrace crate生成当前堆栈的回溯。

当发生恐慌时使用RUST_BACKTRACE=1时,这与内部生锈完全相同。

最简单的例子(取自文档)只是调用backtrace::Backtrac

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)
© www.soinside.com 2019 - 2024. All rights reserved.