Обработчик паники (Panic Handler)
На этом этапе при сборке проекта вы получите такую ошибку:
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);
}
}
}
Можно либо использовать внешний крейт, либо написать обработчик паники вручную. Выбор за вами. Инструмент esp-template на самом деле записывает обработчик паники прямо в файл main.rs, а не подключает отдельный крейт.
Ресурсы: