什么是导致段错误的 Rust 代码示例?

潇洒张*_*潇洒张 3 segmentation-fault rust

我在 Rust 中搜索了一些段错误示例,但现在没有崩溃。Rust 现在能够防止所有段错误吗?是否有可能导致段错误的简单演示?

kmd*_*eko 5

如果unsafe允许使用代码,则:

fn main() {
    unsafe { std::ptr::null_mut::<i32>().write(42) };
}
Run Code Online (Sandbox Code Playgroud)

结果是:

   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 1.37s
     Running `target/debug/playground`
timeout: the monitored command dumped core
/playground/tools/entrypoint.sh: line 11:     7 Segmentation fault      timeout --signal=KILL ${timeout} "$@"
Run Code Online (Sandbox Code Playgroud)

正如在操场上看到的那样。


任何会触发段错误的情况都需要在某个时候调用未定义的行为。允许编译器优化代码或以其他方式利用永远不会发生未定义行为的事实,因此很难保证某些代码会出现段错误。编译器完全有权在不触发段错误的情况下运行上述程序。

例如,上面的代码在发布模式下编译时会导致“非法指令”。


如果unsafe不允许使用代码,请参阅Rust 如何保证内存安全并防止段错误?Rust 如何保证它不会发生,只要它的内存安全不变量不被违反(这只能在unsafe代码中发生)。

如果可以避免,请不要使用不安全的代码。


Cer*_*rus 5

严格来说,总是有可能诱使程序认为它有分段错误,因为这是操作系统发送的信号:

use libc::kill;
use std::process;

fn main() {
    unsafe {
        // First SIGSEGV will be consumed by Rust runtime
        // (see https://users.rust-lang.org/t/is-sigsegv-handled-by-rust-runtime/45680)...
        kill(process::id() as i32, libc::SIGSEGV);
        // ...but the second will crash the program, as expected
        kill(process::id() as i32, libc::SIGSEGV);
    }
}
Run Code Online (Sandbox Code Playgroud)

操场

这并不是您问题的真正答案,因为这不是“真正的”分段错误,而是从字面上理解这个问题 - Rust 程序仍然可以以“分段错误”错误结束,这里有一个可靠地触发它的案例。

  • 实际上,使用 nix crate 似乎更好: `signal::raise(signal::Signal::SIGSEGV).unwrap();` (遗憾的是,我只相信 Unix) (2认同)