14 个版本
0.4.3 | 2024 年 8 月 10 日 |
---|---|
0.4.2 | 2024 年 5 月 19 日 |
0.4.1 | 2024 年 1 月 7 日 |
0.4.0 | 2023 年 9 月 22 日 |
0.3.0 | 2022 年 11 月 20 日 |
#6 在 Cargo 插件
每月下载量 2,887
28KB
424 代码行
cargo-careful
cargo careful
是一个运行 Rust 代码时格外谨慎的工具 — 选择启用一些仅在夜间构建时才可用的额外检查,以帮助检测未定义行为,并使用带有调试断言的标准库。当程序使用调试断言构建时,标准库会检查一些未定义行为,但由于这些检查的性能影响被认为太高,其中一些检查被禁用。例如,它将在以下代码片段中找到对齐问题
fn main() {
let arr = [1u8, 2, 3, 4];
for n in [0, 1] {
let val = unsafe { arr.as_ptr().add(n).cast::<u16>().read() };
println!("The value is {val}!");
}
}
要使用 cargo careful
,首先安装它
cargo install cargo-careful
然后在您的项目中运行以下命令
cargo +nightly careful test
您还可以使用 cargo +nightly careful run
来执行二进制包。所有 cargo test
和 cargo run
标志均受支持。
运行 cargo careful
需要最近的夜间工具链。支持过去 3 个月的夜间版本。
第一次运行 cargo careful
时,需要运行一些设置步骤,这需要 rustc-src
rustup 组件 -- 如果需要,工具将为您安装它。
它做了什么?
检测未定义行为
最重要的事情是 cargo careful
做的是使用调试断言构建标准库。当使用调试断言构建程序时,标准库会检查一些未定义行为,但由于性能影响太大,其中一些检查被禁用。此外,cargo careful
还设置了一些标志,告诉 rustc 插入额外的运行时检查。
以下是一些它启用的检查
ptr.read()
/ptr.write(v)
检查指针是否对齐且非空。- 收集类型执行了大量的内部一致性检查。
mem::zeroed
和已弃用的mem::uninitialized
在类型不允许这种初始化(使用比默认更严格的检查)时引发恐慌。 (这是-Zstrict-init-checks
。)- 在常量评估期间进行额外的未定义行为检查。 (这是
-Zextra-const-ub-checks
。)
尽管如此,有许多未定义行为是 无法 通过 cargo careful
检测到的;如果您想进行更彻底的覆盖,请查看 Miri。与 Miri 相比,cargo careful
的优势在于它适用于所有代码,支持使用任意系统和 C FFI 函数,并且速度要快得多。
RUSTFLAGS
cargo careful
遵循 cargo careful
的环境变量以及 build.rustflags
设置(按顺序,首先设置的变量被使用)。目前它不遵循 target.rustflags
设置,因为这需要重新实现所有目标 cfg
逻辑。标志应用于 两个 系统库构建和程序本身。
清理
cargo careful
可以还构建和运行您的程序和标准库,同时使用清理器。此功能为实验性功能,默认情况下是禁用的。
底层的 -Zextra-const-ub-checks
功能与 过程宏 不兼容。如果您在构建过程中遇到涉及过程宏的错误消息,有时可以通过指定目标(可以是主机相同的)来解决,例如 --target=x86_64-unknown-linux-gnu
。
要使用消毒器,请通过命令行标志 -Zcareful-sanitizer=<your_sanitizer>
将 cargo careful
传递。支持的消毒器和目标列表可以在 这里 找到。如果您传递 -Zcareful-sanitizer
而没有指定消毒器,将使用 AddressSanitizer
。
默认情况下,当使用 AddressSanitizer
时,cargo careful
将通过在您的程序环境中设置 ASAN_OPTIONS=detect_leaks=0
来禁用内存泄漏检查,因为内存泄漏通常不是健壮性或正确性问题。如果您自己设置 ASAN_OPTIONS
环境变量(包括空字符串在内的任何值),则将覆盖此行为。
主线程检查器
cargo careful
在用户安装了 Xcode 时,会自动在 macOS、iOS、tvOS 和 watchOS 目标上启用 Apple 的主线程检查器。
这有助于诊断在这些平台上执行主线程之外的线程不安全功能时的问题。
cfg 标志
cargo careful
设置了 careful
配置标志,因此您可以使用 Rust 的编译时条件机制(例如 #[cfg(careful)]
、#[cfg_attr(careful, ...)]
、cfg!(careful)
)来检查代码是否被谨慎运行。
依赖项
~2–15MB
~147K SLoC