Skip to content

Commit 3fdb520

Browse files
committed
Introduce basic usage of Miri in the unsafe chapter
1 parent 48d0b76 commit 3fdb520

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
$ cargo +nightly miri run
2+
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.01s
3+
Running `/Users/chris/.rustup/toolchains/nightly-aarch64-apple-darwin/bin/cargo-miri runner target/miri/aarch64-apple-darwin/debug/unsafe-example`
4+
warning: creating a shared reference to mutable static is discouraged
5+
--> src/main.rs:14:33
6+
|
7+
14 | println!("COUNTER: {}", COUNTER);
8+
| ^^^^^^^ shared reference to mutable static
9+
|
10+
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
11+
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
12+
= note: `#[warn(static_mut_refs)]` on by default
13+
14+
COUNTER: 3

src/ch20-01-unsafe-rust.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,13 +457,56 @@ interface with unions in C code. Accessing union fields is unsafe because Rust
457457
cant guarantee the type of the data currently being stored in the union
458458
instance. You can learn more about unions in [the Rust Reference][reference].
459459
460+
### Using Miri to check unsafe code
461+
462+
When writing unsafe code, you might want to check that what you have written
463+
actually is safe and correct. One of the best ways to do that is to use
464+
[Miri][miri], an official Rust tool for detecting undefined behavior. Whereas
465+
the borrow checker is a *static* tool which works at compile time, Miri is a
466+
*dynamic* tool which works at runtime. It checks your code by running your
467+
program, or its test suite, and detecting when you violate the rules its
468+
understands about how Rust should work.
469+
470+
Using Miri requires a nightly build of Rust (which we talk about more in
471+
[Appendix G: How Rust is Made and “Nightly Rust”][nightly]). You can install
472+
both a nightly version of Rust and the Miri tool by typing `rustup +nightly
473+
component add miri`. This does not change what version of Rust your project
474+
uses; it only adds the tool to your system so you can use it when you want to.
475+
You can run Miri on a project by typing `cargo +nightly miri run` or `cargo
476+
+nightly miri test`.
477+
478+
For an example of how helpful this can be, consider what happens when we run it
479+
against Listing 20-10:
480+
481+
```console
482+
{{#include ../listings/ch20-advanced-features/listing-20-10/output.txt}}
483+
```
484+
485+
It helpfully and correctly notices that we have shared references to mutable
486+
data, and warns about it. In this case, it does not tell us how to fix the
487+
problem, but it means that we know there is a possible issue and can think about
488+
how to make sure it is safe. In other cases, it can actually tell us that some
489+
code is *sure* to be wrong and make recommendations about how to fix it.
490+
491+
Miri doesn’t catch *everything* you might get wrong when writing unsafe code.
492+
For one thing, since it is a dynamic check, it only catches problems with code
493+
that actually gets run. That means you will need to use it in conjunction with
494+
good testing techniques to increase your confidence about the unsafe code you
495+
have written. For another thing, it does not cover every possible way your code
496+
can be unsound. If Miri *does* catch a problem, you know there’s a bug, but just
497+
because Miri *doesn’t* catch a bug doesn’t mean there isn’t a problem. Miri can
498+
catch a lot, though. Try running it on the other examples of unsafe code in this
499+
chapter and see what it says!
500+
460501
### When to Use Unsafe Code
461502
462503
Using `unsafe` to take one of the five actions (superpowers) just discussed
463504
isn’t wrong or even frowned upon. But it is trickier to get `unsafe` code
464505
correct because the compiler can’t help uphold memory safety. When you have a
465506
reason to use `unsafe` code, you can do so, and having the explicit `unsafe`
466507
annotation makes it easier to track down the source of problems when they occur.
508+
Whenever you write unsafe code, you can use Miri to help you be more confident
509+
that the code you have written upholds Rust’s rules.
467510
468511
[dangling-references]:
469512
ch04-02-references-and-borrowing.html#dangling-references
@@ -473,3 +516,5 @@ ch03-01-variables-and-mutability.html#constants
473516
ch16-04-extensible-concurrency-sync-and-send.html#extensible-concurrency-with-the-sync-and-send-traits
474517
[the-slice-type]: ch04-03-slices.html#the-slice-type
475518
[reference]: ../reference/items/unions.html
519+
[miri]: https://github.com/rust-lang/miri
520+
[nightly]: appendix-07-nightly-rust.html

0 commit comments

Comments
 (0)