Обработчик паники
На этом этапе при сборке проекта вы получите такую ошибку:
error: `#[panic_handler]` function required, but not found
Когда программа на Rust паникует, обычно паника обрабатывается встроенным обработчиком из стандартной библиотеки. Но на предыдущем шаге мы добавили #![no_std], который говорит Rust не использовать стандартную библиотеку. Поэтому по умолчанию обработчика паники теперь нет.
В окружении no_std вы сами должны определить поведение при панике, потому что при возникновении проблемы некому перехватить управление: ни операционной системы, ни среды выполнения нет.
Исправить это можно, добавив собственный обработчик паники. Просто создайте функцию с атрибутом #[panic_handler]. Функция должна принимать ссылку на PanicInfo, а её возвращаемый тип должен быть !, что означает, что функция никогда не возвращает управление.
Добавьте это в src/main.rs:
#![allow(unused)]
fn main() {
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
loop {}
}
}
Крейты для паники
Есть готовые крейты, которые предоставляют функцию-обработчик паники для проектов no_std. Один из простых и часто используемых — “panic_halt”, который просто останавливает выполнение при панике.
#![allow(unused)]
fn main() {
use panic_halt as _;
}
Эта строка подключает обработчик паники из крейта. Теперь, если случится паника, программа просто остановится и будет крутиться в бесконечном цикле.
На самом деле код крейта panic_halt реализует простой обработчик паники, который выглядит так:
#![allow(unused)]
fn main() {
use core::panic::PanicInfo;
use core::sync::atomic::{self, Ordering};
#[inline(never)]
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {
atomic::compiler_fence(Ordering::SeqCst);
}
}
}
Можно либо использовать внешний крейт, как здесь, либо написать собственную функцию-обработчик вручную. Выбор за вами.
Ресурсы:
- Официальная документация Rust, раздел о обработчике паники (на английском языке)
- The Embedded Rust Book, раздел о панике (на английском языке)