< 返回我的博客

爱国的张浩予 发表于 2021-03-10 12:34

Tags:panic,panic_handler,set_hook,Unwinding,Abort

首先,有两种处理方式

  • 自解绑Unwinding(默认)。即,沿着【函数-调用栈】,由rust程序自身逐一释放每一个正在被调用函数所占用的内存。
  • 立即结束进程Abort,由操作系统(或wasm的宿主【浏览器】)负责进程内存的回收。

其次,上述两种处理方式的优缺点包括

  • 自解绑Unwinding能够提供
    • 【程序崩溃】自描述信息(如果被提供的话)

    • 【程序崩溃】的位置信息,包括:

      • 文件名
      • 行号
      • 列号
    • 【程序崩溃】发生时的【函数-调用栈】(术语:回溯backtrace),若在程序编译时,准备了如下配置:

      • 首先,设置了环境变量RUST_BACKTRACE=1
      • 其次,开启了【DEBUG模式】(即,在cargo build/run指令里不添加--release命令行参数)。

      这个信息对推测崩溃原因很有帮助。

    • 立即结束进程Abort能够让编译输出的二进制文件“体积”更小。

      wasmweb使用场景】表示很中意。

接着,rustc提供给开发者三种途径来指定如何处理【程序崩溃】

  • Cargo.toml文件中的(如下)配置项。针对【产品-分发包】,开启Abort崩溃退出模式。

    [profile.release]
    panic = "abort"
    
    • 配置发生于:编译时。
  • rust代码内的#[panic_handler]元属性。由此元属性修饰的函数fn(&PanicInfo) -> ! {...}将会重写来自【标准库std】的【程序崩溃panic】默认处理行为。

    • 配置发生于:编译时。
    • 全域至多只能有一个#[panic_handler]元属性。
  • 调用std::panic::set_hook(Box<dyn Fn(&PanicInfo<'_>) + Sync + Send + 'static>)函数,挂载【程序崩溃panic】处理闭包。

    • 配置发生于:运行时。
    • 新挂载的处理闭包会替换旧挂载的闭包。
    • 若多次调用set_hook函数挂载panic处理闭包,则只有最后一次被挂载的处理闭包会生效。

评论区

写评论

还没有评论

1 共 0 条评论, 1 页