RustのCrate調査 (better-panic)

Rust製の実行ファイルが異常終了した際に出力されるスタックトレースを、見た目の良いものに置き換えてくれるcrateを発見し、さっそく使ってみました。

crateの名前は「better-panic」です。 作者はPythonのflaskで有名な「mitsuhiko」ことArmin Ronacher氏。

github.com

コンパイラのバージョンは「rustc 1.35.0」、「better-panic = "0.1.1"」で試してみたいと思います。

better-panic適用前

例えば、次のようなソースコードを用意して、実行したら必ずpanicになるようにします。

fn main() {
    println!("Hello, world!");
    panic!("Encounter Panic!");
}

通常ですと、次のようなエラーメッセージが表示され、環境変数としてRUST_BACKTRACE=1をセットしないといけないな、となります。

Hello, world!
thread 'main' panicked at 'Encounter Panic!', src/main.rs:3:5
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

環境変数をセットしてから再び実行した結果が、次の内容です。

Hello, world!
thread 'main' panicked at 'Encounter Panic!', src/main.rs:3:5
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:39
   1: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:71
   2: std::panicking::default_hook::{{closure}}
             at src/libstd/sys_common/backtrace.rs:59
             at src/libstd/panicking.rs:197
   3: std::panicking::default_hook
             at src/libstd/panicking.rs:211
   4: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:474
   5: std::panicking::begin_panic
             at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e/src/libstd/panicking.rs:408
   6: try_better_panic::main
             at src/main.rs:3
   7: std::rt::lang_start::{{closure}}
             at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e/src/libstd/rt.rs:64
   8: std::panicking::try::do_call
             at src/libstd/rt.rs:49
             at src/libstd/panicking.rs:293
   9: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:87
  10: std::rt::lang_start_internal
             at src/libstd/panicking.rs:272
             at src/libstd/panic.rs:388
             at src/libstd/rt.rs:48
  11: std::rt::lang_start
             at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e/src/libstd/rt.rs:64
  12: main
  13: __libc_start_main
  14: _start

自分が作成したソースコード以外のスタックが、こんなにも積まれていたことに気づいた瞬間です。

全部出力されると、余計な部分も多く、自分のコードがどこなのかわからないですね。

better-panic適用後

プログラムの最初に、better_panic::install()を追加します。

fn main() {
    better_panic::install(); // add better-panic!
    println!("Hello, world!");
    panic!("Encounter Panic!");
}

これによって、置き換えられたスタックトレースがこちらになります。

f:id:toyamaguchi:20190621191837p:plain

カラフルになり、自分のソースコードの箇所だけスタックトレースが表示されるようになりました。

また、スレッド情報も書いてあるようなので、マルチスレッドのプログラムが異常終了した場合でも、どのスレッドで問題があったのかがわかるかもしれません。

実行した環境にソースファイルを見つけた場合、そのソーススニペットを表示してくれるそうです。

まとめ

今回はbetter-panicについて調査をしました。

GitHubにも書かれていますが、これはPythonのtracebackからインスパイアされて作ったそうです。

また、気になるcrateがあったら調査していこうと思います。