Rust嵌入式开发库esp-backtrace的使用:ESP32/ESP8266异常堆栈追踪与调试工具

Rust嵌入式开发库esp-backtrace的使用:ESP32/ESP8266异常堆栈追踪与调试工具

esp-backtrace是一个为ESP32系列裸机开发提供的堆栈追踪库,支持ESP32、ESP32-C2/C3/C6、ESP32-H2、ESP32-P4和ESP32-S2/S3等芯片。

特性

特性 描述
esp32 目标ESP32
esp32c2 目标ESP32-C2
esp32c3 目标ESP32-C3
esp32c6 目标ESP32-C6
esp32h2 目标ESP32-H2
esp32p4 目标ESP32-P4
esp32s2 目标ESP32-S2
esp32s3 目标ESP32-S3
panic-handler 包含panic处理程序,会添加esp-println作为依赖
exception-handler 包含异常处理程序,会添加esp-println作为依赖
println 使用esp-println打印消息
defmt 使用defmt日志打印消息
colors 用红色打印消息
halt-cores 在ESP32/ESP32-S3上发生panic或异常时停止两个CPU而不是进入loop {}
semihosting 在panic时调用semihosting::process::abort()
custom-halt 在panic或异常时调用外部函数custom_halt()而不是进入loop {}
custom-pre-backtrace 在panic或异常处理前调用外部函数custom_pre_backtrace()

使用说明

  1. 当目标是RISC-V设备时,需要强制使用帧指针(即在.cargo/config.toml中添加"-C", "force-frame-pointers"),对于Xtensa则不需要。

  2. 可以通过arch::backtrace()获取堆栈地址数组(目前限制为10个),如果你想自己创建堆栈追踪(即不使用panic或异常处理程序)。

  3. 当使用panic和/或异常处理程序时,确保包含use esp_backtrace as _;

示例代码

// 在Cargo.toml中添加依赖
// esp-backtrace = "0.17.0"

use esp_backtrace as _; // 引入panic和异常处理程序

fn main() {
    // 强制触发一个panic
    panic!("This is a test panic");
    
    // 或者手动获取堆栈追踪
    // let backtrace = arch::backtrace();
    // println!("Backtrace: {:?}", backtrace);
}

完整示例代码

// Cargo.toml 依赖配置
/*
[dependencies]
esp-backtrace = { version = "0.17.0", features = ["panic-handler", "println"] }
*/

// main.rs
use esp_backtrace as _; // 引入panic处理程序

// 自定义函数用于演示堆栈追踪
fn cause_panic() {
    // 这里会触发panic
    panic!("Intentional panic for backtrace demonstration");
}

fn another_function() {
    // 调用会触发panic的函数
    cause_panic();
}

fn main() {
    // 打印初始化信息
    println!("Starting backtrace demo...");
    
    // 调用链: main -> another_function -> cause_panic -> panic!
    another_function();
    
    // 这行代码不会执行,因为前面已经panic了
    println!("This line won't be reached");
}

// 目标为RISC-V时的配置示例 (放在.cargo/config.toml中)
/*
[target.riscv32imc-unknown-none-elf]
rustflags = ["-C", "force-frame-pointers"]
*/

配置示例

.cargo/config.toml中添加(针对RISC-V设备):

[target.riscv32imc-unknown-none-elf]
rustflags = ["-C", "force-frame-pointers"]

安装

在项目目录中运行以下Cargo命令:

cargo add esp-backtrace

或者在Cargo.toml中添加:

esp-backtrace = "0.17.0"

许可证

本库采用以下任一许可证:

  • Apache License, Version 2.0
  • MIT license

最低支持的Rust版本(MSRV)

本库保证在发布时的最新稳定Rust版本下编译通过。它可能能在旧版本下编译,但这可能在新的发布(包括补丁)中改变。


1 回复

esp-backtrace: ESP32/ESP8266异常堆栈追踪与调试工具

介绍

esp-backtrace是一个专门为ESP32和ESP8266嵌入式设备设计的Rust库,用于在发生异常时捕获和显示调用堆栈信息。这对于嵌入式开发中的调试非常有用,特别是在难以复现的崩溃或异常情况下。

该库提供了以下主要功能:

  • 捕获panic时的调用堆栈
  • 显示详细的函数调用链
  • 支持裸机(no-std)环境
  • 可定制的输出方式

完整示例代码

// 引入esp-backtrace库
use esp_backtrace as _;
use esp_backtrace::Settings;

// 定义一个会panic的函数
fn trigger_panic() {
    panic!("Function triggered panic!");
}

// 主函数
fn main() {
    // 初始化backtrace处理器(带自定义设置)
    esp_backtrace::init_with_settings(
        Settings::new()
            .max_depth(16)   // 限制堆栈追踪深度为16层
            .detailed(true)  // 启用详细符号信息
    );

    println!("Application started");

    // 调用会panic的函数
    trigger_panic();

    // 这行代码不会执行
    println!("This line will not be reached");
}

// 中断处理函数示例
#[interrupt]
fn TIMER0() {
    // 手动打印当前堆栈
    println!("Interrupt TIMER0 occurred");
    esp_backtrace::print_backtrace();
    
    // 或者可以直接panic
    // panic!("Interrupt context panic");
}

预期输出示例

当上述代码运行时,会输出类似以下内容:

Application started
Panic occurred at src/main.rs:6:
Function triggered panic!
Backtrace:
0x400d1234: app::trigger_panic::h12345678 at src/main.rs:6
0x400d5678: app::main::h98765432 at src/main.rs:15
0x400d9012: core::ops::function::FnOnce::call_once::h56789012 at /rustc/.../library/core/src/ops/function.rs:227
...

注意事项

  1. 确保你的项目配置了正确的调试符号(debug = true)
  2. 在release构建中,堆栈信息可能不太准确
  3. 对于ESP8266,可能需要额外的配置来支持完整的backtrace功能
  4. 堆栈追踪会消耗额外的RAM,在资源受限的设备上要谨慎使用

故障排除

如果backtrace没有正确显示:

  • 检查是否调用了init()函数
  • 确保panic没有被其他处理程序捕获
  • 验证设备有足够的堆栈空间
  • 检查链接器脚本是否正确配置
回到顶部