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 模式

Download history 9620/week @ 2024-05-04 9860/week @ 2024-05-11 10634/week @ 2024-05-18 11142/week @ 2024-05-25 10025/week @ 2024-06-01 10411/week @ 2024-06-08 10355/week @ 2024-06-15 11599/week @ 2024-06-22 12710/week @ 2024-06-29 12796/week @ 2024-07-06 12827/week @ 2024-07-13 12534/week @ 2024-07-20 11733/week @ 2024-07-27 13187/week @ 2024-08-03 12606/week @ 2024-08-10 10247/week @ 2024-08-17

49,733 每月下载
用于 13 个 crate (5 直接)

MIT/Apache

105KB
3K SLoC

Rust 和 Rust 中的展开库

crates.io docs.rs license

本库有两个目的

  1. 提供对 libgcc_eh 或 libunwind 的纯 Rust 替代方案。
  2. #![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 和其他动态注册功能。需要 libcspin 以实现互斥锁。
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_paniccatch_unwind。只提供堆栈unwinding功能,内存分配和panic处理留给用户。
panic 提供Rust的begin_paniccatch_unwind。只提供堆栈unwinding功能,不进行打印,因为此功能不依赖于libc。
panic处理器 提供#[panic_handler]。提供类似于std的panic行为,并支持RUST_BACKTRACE。但是堆栈跟踪不会包含符号。依赖于libc。
系统分配 提供一个全局分配器,它会调用malloc和类似的函数。为了方便而提供。

如果您正在编写一个#![no_std]程序,只需在默认设置中启用personalitypanic-handlersystem-alloc即可,您立即获得执行unwinding的能力!示例可以在example/文件夹中找到。

裸机

为了在裸机项目中使用这个库,禁用默认功能并启用unwinderfde-staticpersonalitypanicdwarf-exprhide-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_localprintln! 并且它们正在运行,您可以为双重panic保护和堆栈跟踪移植 panic_handler.rs

依赖项

~2MB
~42K SLoC