update unsafe-rust

pull/417/head
sunface 3 years ago
parent f84552f9ea
commit aceeee5e1e

@ -331,9 +331,75 @@ union MyUnion {
关于 `union` 的更多信息,可以在[这里查看](https://doc.rust-lang.org/reference/items/unions.html)。
## 一些实用工具(库)
由于 `unsafe``FFI` 在 Rust 的使用场景中是相当常见的(例如相对于 Go 的 `unsafe` 来说),因此社区已经开发出了相当一部分实用的工具,可以改善相应的开发体验。
#### rust-bindgen 和 cbindgen
对于 `FFI` 调用来说,保证接口的正确性是非常重要的,这两个库可以帮我们自动生成相应的接口,其中 [`rust-bindgen`](https://github.com/rust-lang/rust-bindgen) 用于在 Rust 中访问 C 代码,而 [`cbindgen`](https://github.com/eqrion/cbindgen/)则反之。
下面以 `rust-bindgen` 为例,来看看如何自动生成调用 C 的代码,首先下面是 C 代码:
```c
typedef struct Doggo {
int many;
char wow;
} Doggo;
void eleven_out_of_ten_majestic_af(Doggo* pupper);
```
下面是自动生成的可以调用上面代码的 Rust 代码:
```rust
/* automatically generated by rust-bindgen 0.99.9 */
#[repr(C)]
pub struct Doggo {
pub many: ::std::os::raw::c_int,
pub wow: ::std::os::raw::c_char,
}
extern "C" {
pub fn eleven_out_of_ten_majestic_af(pupper: *mut Doggo);
}
```
#### cxx
如果需要跟 C++ 代码交互,非常推荐使用 [`cxx`](https://github.com/dtolnay/cxx),它提供了双向的调用,最大的优点就是安全:是的,你无需通过 `unsafe` 来使用它!
#### Miri
[`miri`](https://github.com/rust-lang/miri) 可以生成 Rust 的中间层表示 MIR对于编译器来说我们的 Rust 代码首先会被编译为 MIR ,然后再提交给 LLVM 进行处理。
可以通过 `rustup component add miri` 来安装它,并通过 `cargo miri` 来使用,同时还可以使用 `cargo miri test` 来运行测试代码。
`miri` 可以帮助我们检查常见的未定义行为(UB = Undefined Behavior),以下列出了一部分:
- 内存越界检查和内存释放后再使用(use-after-free)
- 使用未初始化的数据
- 数据竞争
- 内存对齐问题
但是需要注意的是,它只能帮助识别被执行代码路径的风险,哪些未被执行到的代码是没办法被识别的。
#### Clippy
官方的 [`clippy`](https://github.com/rust-lang/rust-clippy) 检查器提供了有限的 `unsafe` 支持,虽然不多,但是至少有一定帮助。例如 `missing_safety_docs` 检查可以帮助我们检查哪些 `unsafe` 函数遗漏了文档。
需要注意的是: Rust 编译器并不会默认开启所有检查,大家可以调用 `rustc -W help` 来看看最新的信息。
#### Prusti
[`prusti`](https://viperproject.github.io/prusti-dev/user-guide/) 需要大家自己来构建一个证明,然后通过它证明代码中的不变量是正确被使用的,当你在安全代码中使用不安全的不变量时,就会非常有用。具体的使用文档见[这里](https://viperproject.github.io/prusti-dev/user-guide/)。
#### 模糊测试(fuzz testing)
在 [Rust Fuzz Book](https://rust-fuzz.github.io/book/) 中列出了一些 Rust 可以使用的模糊测试方法。
同时,我们还可以使用 [`rutenspitz`](https://github.com/jakubadamw/rutenspitz) 这个过程宏来测试有状态的代码,例如数据结构。
## 总结
至此,`unsafe` 的五种兵器已介绍完毕,大家是否意犹未尽?我想说的是,就算意犹未尽,也没有其它武器了。
就像上一章中所提到的,`unsafe` 只应该用于这五种场景,其它场景,你应该坚决的使用安全的代码,否则就会像 `actix-web` 的前作者一样,被很多人议论,甚至被喷。。。
总之,能不使用 `unsafe` 一定不要使用,就算使用也要控制好边界,让范围尽可能的小,就像本章的例子一样,只有真的需要 `unsafe` 的代码,才应该包含其中, 而不是将无关代码也纳入进来。
总之,能不使用 `unsafe` 一定不要使用,就算使用也要控制好边界,让范围尽可能的小,就像本章的例子一样,只有真的需要 `unsafe` 的代码,才应该包含其中, 而不是将无关代码也纳入进来。
## 进一步学习
1. [Unsafe Rust: How and when (not) to use it]: https://blog.logrocket.com/unsafe-rust-how-and-when-not-to-use-it/

@ -4,4 +4,6 @@ https://www.reddit.com/r/rust/comments/rnkyc0/why_does_my_code_compile_faster_on
https://www.reddit.com/r/rust/comments/rv8126/speedup_compilation_time/
https://www.reddit.com/r/rust/comments/rsfcgb/why_is_my_rust_build_so_slow/
https://www.reddit.com/r/rust/comments/rsfcgb/why_is_my_rust_build_so_slow/
https://www.reddit.com/r/rust/comments/sqi1ba/is_it_just_me_or_rustanalyzer_is_unreliableslow/

@ -6,4 +6,7 @@ https://www.reddit.com/r/rust/comments/rupcux/how_do_i_profile_a_rust_web_applic
https://zhuanlan.zhihu.com/p/191655266
## 内存对齐
https://www.reddit.com/r/rust/comments/s793x7/force_4byte_memory_alignment/
https://www.reddit.com/r/rust/comments/s793x7/force_4byte_memory_alignment/
## riggrep 为啥这么快
https://www.reddit.com/r/rust/comments/sr02aj/what_makes_ripgrep_so_fast/
Loading…
Cancel
Save