10 个版本
0.2.2 | 2024 年 6 月 25 日 |
---|---|
0.2.1 | 2023 年 10 月 28 日 |
0.2.0 | 2023 年 8 月 6 日 |
0.1.7 | 2023 年 5 月 7 日 |
0.1.3 | 2021 年 10 月 26 日 |
#136 in Rust 模式
49,733 每月下载
用于 13 个 crate (5 直接)
105KB
3K SLoC
Rust 和 Rust 中的展开库
本库有两个目的
- 提供对 libgcc_eh 或 libunwind 的纯 Rust 替代方案。
- 为
#![no_std]
目标提供更简单的展开支持。
目前支持 x86_64、x86、RV64、RV32 和 AArch64。
展开器
可以通过 unwinder
功能启用展开器。以下是与展开器相关的功能门
功能 | 默认 | 描述 |
---|---|---|
unwinder | 是 | 启用展开器的首选功能门 |
fde-phdr-dl | 是 | 使用 dl_iterator_phdr 获取帧展开表。依赖于 libc。 |
fde-phdr-aux | 否 | 使用 ELF 辅助向量获取帧展开表。依赖于 libc。 |
fde-registry | 是 | 提供 __register__frame 和其他动态注册功能。需要 libc 或 spin 以实现互斥锁。 |
fde-gnu-eh-frame-hdr | 否 | 使用 __executable_start 、__etext 和 __GNU_EH_FRAME_HDR 获取帧展开表。前两个符号通常由连接器提供,而最后一个符号在启用 GNU LD 和 --eh-frame-hdr 选项时提供。 |
fde-static | 否 | 使用 __executable_start 、__etext 和 __eh_frame 获取帧展开表。前两个符号通常由连接器提供,而最后一个符号需要用户通过连接器脚本提供。 |
fde-custom | 否 | 允许程序通过 set_custom_eh_frame_finder 函数在运行时提供自定义获取帧展开表的方法。 |
dwarf-expr | 是 | 启用 dwarf 表达式求值器。通常对于 Rust 不是必需的 |
hide-trace | 是 | 隐藏回溯中的展开器帧 |
如果您想为其他Rust(C++或任何使用unwinder的程序)使用unwinder,可以构建提供的unwinding_dyn
crate,并使用LD_PRELOAD
来用其替换系统unwinder。
cd cdylib
cargo build --release
# Test the unwinder using rustc. Why not :)
LD_PRELOAD=`../target/release/libunwinding_dyn.so` rustc +nightly -Ztreat-err-as-bug
如果您想将unwinder链接到Rust二进制文件中,只需添加
extern crate unwinding;
人格和其它工具
该库还提供了Rust人格函数。它可以与上述unwinder或其他unwinder一起使用。如果您正在开发一个#![no_std]
二进制文件/staticlib/cdylib,并且仍然需要unwinding支持,这将非常有用。
以下是相关的功能门
功能 | 默认 | 描述 |
---|---|---|
人格 | 否 | 提供#[lang = eh_personality] |
打印 | 否 | 提供(e)?print(ln)? 。这仅仅是因为panic处理器需要打印一些东西。依赖于libc。 |
panic | 否 | 提供通用的begin_panic 和catch_unwind 。只提供堆栈unwinding功能,内存分配和panic处理留给用户。 |
panic | 否 | 提供Rust的begin_panic 和catch_unwind 。只提供堆栈unwinding功能,不进行打印,因为此功能不依赖于libc。 |
panic处理器 | 否 | 提供#[panic_handler] 。提供类似于std的panic行为,并支持RUST_BACKTRACE 。但是堆栈跟踪不会包含符号。依赖于libc。 |
系统分配 | 否 | 提供一个全局分配器,它会调用malloc 和类似的函数。为了方便而提供。 |
如果您正在编写一个#![no_std]
程序,只需在默认设置中启用personality
、panic-handler
和system-alloc
即可,您立即获得执行unwinding的能力!示例可以在example/
文件夹中找到。
裸机
为了在裸机项目中使用这个库,禁用默认功能并启用unwinder
、fde-static
、personality
、panic
。 dwarf-expr
和hide-trace
是可选的。通过修改链接器脚本来实现
/* Inserting these two lines */
. = ALIGN(8);
PROVIDE(__eh_frame = .);
/* before .eh_frame rule */
.eh_frame : { KEEP (*(.eh_frame)) *(.eh_frame.*) }
就这样!在确保全局分配器功能正常之后,您可以使用unwinding::panic::begin_panic
来启动unwinding并使用unwinding::panic::catch_unwind
来捕获,就像您拥有一个std
。
如果您的链接器支持 --eh-frame-hdr
,您也可以尝试使用 fde-gnu-eh-frame-hdr
代替 fde-static
。GNU LD 将提供 __GNU_EH_FRAME_HDR
魔术符号,因此您不需要通过链接器脚本提供 __eh_frame
。
如果您有自己版本的 thread_local
和 println!
并且它们正在运行,您可以为双重panic保护和堆栈跟踪移植 panic_handler.rs
!
依赖项
~2MB
~42K SLoC