Какой пример кода Rust вызывает segfault? - PullRequest
2 голосов
/ 11 июля 2020

Я погуглил несколько примеров segfault в Rust, но сейчас ни одного из cra sh. Может ли Rust теперь предотвратить все ошибки сегментации? Есть ли простая демонстрация, которая может вызвать segfault?

Ответы [ 3 ]

4 голосов
/ 11 июля 2020

Строго говоря, всегда можно обмануть программу, заставив думать, что в ней произошла ошибка сегментации, поскольку это сигнал, отправленный ОС:

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);
    }
}

Playground

На самом деле это не ответ на ваш вопрос, поскольку это не «настоящая» ошибка сегментации, но если понимать вопрос буквально - программа Rust все еще может завершиться ошибкой «ошибки сегментации», и вот случай, который надежно запускает его.

2 голосов
/ 20 июля 2020

Если вы в более общем плане ищете что-то, что будет сбрасывать ядро, а не конкретно вызывать segfault, есть другой вариант, который заставляет компилятор выдавать инструкцию UD2 или эквивалентную. Вот несколько вещей, которые могут вызвать это:

2 голосов
/ 11 июля 2020

Если разрешен код unsafe, то:

fn main() {
    unsafe { std::ptr::null_mut::<i32>().write(42) };
}

приводит к:

   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} "$@"

, как показано на площадке .

Любая ситуация, которая может вызвать segfault, в какой-то момент потребует вызова неопределенного поведения. Компилятору разрешено оптимизировать код или иным образом использовать тот факт, что неопределенное поведение никогда не должно происходить, поэтому очень сложно гарантировать , что некоторый код будет иметь ошибку segfault. Компилятор вполне вправе заставить указанную выше программу запускаться без запуска segfault.

В качестве примера приведенный выше код при компиляции в режиме release вместо этого приводит к появлению «Недопустимой инструкции» .

Если код unsafe не разрешен, см. Как Rust гарантирует безопасность памяти и предотвращает ошибки сегментации? , чтобы узнать, как Rust может гарантировать, что этого не произойдет, пока его инварианты безопасности памяти не нарушаются. (что могло произойти только в коде unsafe).

Не используйте небезопасный код, если вы можете этого избежать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...