Извлечь след от паники в крючке в Rust? - PullRequest
0 голосов
/ 28 февраля 2019

Моему приложению нужно отправлять журналы на fluentd в формате JSON через стандартный вывод.
Пока я пытаюсь обработать панику и организовать &std::panic::PanicInfo в виде JSON с std::panic::set_hook, я мог быне найти способ получить backtrace из &PanicInfo.

Есть ли способ получить обратную трассировку от паники в пользовательском хуке?

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

PanicInfo не содержит следа, но вы можете захватить его самостоятельно в панике.

Из документации set_hook:

Регистрирует пользовательский хук паники, заменяя любой ранее зарегистрированный.

Хук паники вызывается, когда поток паникует, но до того, как вызывается среда выполнения паники.Таким образом, крюк будет работать как во время прерывания, так и во время размотки.Хук по умолчанию печатает сообщение со стандартной ошибкой и генерирует обратную трассировку, если требуется, но это поведение можно настроить с помощью функций set_hook и take_hook.

Поскольку хук паники запускается перед тем, как раскрутить , вы можете самостоятельно захватить след в паническом крюке, используя ящик backtrace, уже упомянутый @hellow:

panic::set_hook(Box::new(|panic_info| {
    let backtrace = Backtrace::new();
    //  Do something with backtrace and panic_info.
}));
0 голосов
/ 28 февраля 2019

Вы можете использовать ящик обратной трассировки , чтобы сгенерировать обратную трассировку вашего текущего стека.

Это точно такой же ящик, который используется внутри для ржавчины, когда вы используете 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)
...