パニックハンドラ
Rust における panic が何であるかについては、すでに基本的なイメージを持っているものとします。panic が発生しても、プログラムはすぐには終了しません。代わりに、制御は標準ライブラリが提供するパニックハンドラに渡されます。デフォルトでは、panic を起こしたスレッドのスタックの巻き戻しを開始します。しかし、ユーザーが panic 時に abort するよう選択している場合、プログラムは巻き戻しを行わずにただちに終了します。
この段階でプログラムをビルドしようとすると、次のエラーが表示されます。
error: `#[panic_handler]` function required, but not found
error: unwinding panics are not supported without std
これは、標準ライブラリを使用していないため、カスタムのパニックハンドラを定義する必要があることを意味します。
no_std におけるパニックハンドラ
no_std 環境では、自前のパニックハンドラを用意する必要があります。これを行ってくれる crate があり、必要な挙動に応じて 1 つ選べます。
たとえば次のようなものがあります。
-
プログラムを即座に abort したい場合は、
panic-abortcrate を使えます。 -
無限ループに入ることでプログラム(または現在のスレッド)を停止させたい場合は、
panic-haltcrate を使えます。
これらの crate のソースコードを確認すると、単なるシンプルな関数であることがわかります。
次のように、これらの crate のいずれかをインポートすることもできます。
#![allow(unused)] fn main() { use panic_halt as _; }
あるいは、パニックハンドラ関数を自分で定義することもできます。ここではそれを行います。
この関数には #[panic_handler] 属性を付ける必要があり、core::panic::PanicInfo への参照を受け取らなければなりません。また、この関数は決して返ってこないため、戻り値の型は ! です。
以下がその関数です(panic-halt が提供するものと等価です)。src/main.rs ファイルを更新し、次のコードを含めましょう。
#![allow(unused)] fn main() { #[panic_handler] fn panic(_: &core::panic::PanicInfo) -> ! { loop {} } }
参考
-
The Embedded Rust book の Panicking セクション
-
The Rustonomicaon の panic_handler セクション