【问题标题】:Retrieving backtrace from a panic in hook in Rust?从 Rust 中的钩子恐慌中检索回溯?
【发布时间】:2019-02-28 02:14:07
【问题描述】:

我的应用程序需要通过标准输出将日志以 JSON 格式发送到 fluentd。
当我尝试处理 panics 并将 &std::panic::PanicInfo 安排为带有 std::panic::set_hook 的 JSON 时,我找不到从 &PanicInfo 检索 backtrace 的方法.

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

【问题讨论】:

    标签: logging rust backtrace panic


    【解决方案1】:

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

    来自set_hook 文档:

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

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

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

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

    【讨论】:

    • 我想过提供这个答案,但是在恐慌处理程序中执行复杂逻辑的想法感觉非常冒险......
    【解决方案2】:

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

    这与 rust 在发生恐慌时使用 RUST_BACKTRACE=1 时在内部使用的 crate 完全相同。

    最简单的例子(取自文档)就是调用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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多