Skip to content

Commit a06136b

Browse files
authored
Lightly revise the rest of the documentation (rust-lang#1396)
1 parent c5ec306 commit a06136b

File tree

9 files changed

+123
-99
lines changed

9 files changed

+123
-99
lines changed

docs/src/SUMMARY.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
- [Getting started](./getting-started.md)
44
- [Installation](./install-guide.md)
55
- [Building from source](./build-from-source.md)
6-
- [Usage](./usage.md)
7-
- [On a single file](./kani-single-file.md)
8-
- [On a package](./cargo-kani.md)
6+
- [Using Kani](./usage.md)
97
- [Verification results](./verification-results.md)
108

119
- [Tutorial](./kani-tutorial.md)

docs/src/build-from-source.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ cd kani
2929
git submodule update --init
3030
./scripts/setup/ubuntu/install_deps.sh
3131
./scripts/setup/ubuntu/install_cbmc.sh
32-
./scripts/setup/install_viewer.sh 3.5
33-
./scripts/setup/install_rustup.sh
32+
./scripts/setup/install_viewer.sh
3433
# If you haven't already:
34+
./scripts/setup/install_rustup.sh
3535
source $HOME/.cargo/env
3636
```
3737

3838
### Install dependencies on macOS
3939

40-
Support is available for macOS 10.15. You need to have [Homebrew](https://brew.sh/) installed already.
40+
Support is available for macOS 10.15+. You need to have [Homebrew](https://brew.sh/) installed already.
4141

4242
```
4343
# git clone [email protected]:model-checking/kani.git
@@ -46,9 +46,9 @@ cd kani
4646
git submodule update --init
4747
./scripts/setup/macos-10.15/install_deps.sh
4848
./scripts/setup/macos-10.15/install_cbmc.sh
49-
./scripts/setup/install_viewer.sh 3.5
50-
./scripts/setup/install_rustup.sh
49+
./scripts/setup/install_viewer.sh
5150
# If you haven't already:
51+
./scripts/setup/install_rustup.sh
5252
source $HOME/.cargo/env
5353
```
5454

@@ -74,7 +74,7 @@ All Kani regression tests completed successfully.
7474

7575
## Adding Kani to your path
7676

77-
To use Kani from anywhere, add the Kani scripts to your path:
77+
To use a locally-built Kani from anywhere, add the Kani scripts to your path:
7878

7979
```bash
8080
export PATH=$(pwd)/scripts:$PATH

docs/src/cargo-kani.md

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,3 @@
11
# Usage on a package
22

3-
Kani is also integrated with `cargo` and can be invoked from a crate directory as follows:
4-
5-
```bash
6-
cargo kani [<kani-args>]*
7-
```
8-
9-
`cargo kani` supports all `kani` arguments.
10-
11-
`cargo kani` is the recommended approach for using Kani on a project, due to its
12-
ability to handle external dependencies and the option add configurations via the `Cargo.toml` file.
13-
14-
If your proof harness is placed under `tests/`, you will need to run
15-
`cargo kani` with the `--tests` for Kani to be able to find your
16-
harness.
17-
18-
## Configuration
19-
20-
Users can add a default configuration to the `Cargo.toml` file for running harnesses in a package.
21-
Kani will extract any arguments from these sections:
22-
* `[kani]`
23-
* `[workspace.metadata.kani]`
24-
* `[package.metadata.kani]`
25-
26-
For example, say you want to set a loop unwinding bound of `5` for all the harnesses in a package.
27-
You can achieve this by adding the following lines to the package's `Cargo.toml`:
28-
29-
```toml
30-
[package.metadata.kani]
31-
flags = { default-unwind = "5" }
32-
```
3+
[See here](./usage.md#usage-on-a-package)

docs/src/getting-started.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@
22

33
Kani is an open-source verification tool that uses automated reasoning to analyze Rust programs.
44
Kani is particularly useful for verifying unsafe code in Rust, where many of the Rust’s usual guarantees are no longer checked by the compiler.
5-
Some example properties you can prove with Kani include memory safety properties (e.g., null pointer dereferences, use-after-free, etc.), the absence of certain runtime errors (i.e., panics), and the absence of some types of unexpected behavior (e.g., arithmetic overflows).
5+
Some example properties you can prove with Kani include memory safety properties (e.g., null pointer dereferences, use-after-free, etc.), the absence of certain runtime errors (i.e., index out of bounds, panics), and the absence of some types of unexpected behavior (e.g., arithmetic overflows).
66
Kani can also prove custom properties provided in the form of user-specified assertions.
77

8-
Kani uses proof harnesses to analyze programs. Proof harnesses are similar to test harnesses, especially property-based test harnesses.
8+
Kani uses proof harnesses to analyze programs.
9+
Proof harnesses are similar to test harnesses, especially property-based test harnesses.
910

1011
## Project Status
1112

12-
Kani is currently under active development. Releases are published [here](https://github.com/model-checking/kani/releases).
13+
Kani is currently under active development.
14+
Releases are published [here](https://github.com/model-checking/kani/releases).
1315
There is support for a fair amount of Rust language features, but not all (e.g., concurrency).
1416
Please see [Limitations - Rust feature support](./rust-feature-support.md) for a detailed list of supported features.
1517

16-
Kani usually synchronizes with the nightly release of Rust every two weeks, and so is generally up-to-date with the latest Rust language features.
18+
Kani releases every two weeks.
19+
As part of every release, Kani will synchronize with a recent nightly release of Rust, and so is generally up-to-date with the latest Rust language features.
1720

1821
If you encounter issues when using Kani, we encourage you to [report them to us](https://github.com/model-checking/kani/issues/new/choose).

docs/src/kani-single-file.md

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,3 @@
11
# Usage on a single file
22

3-
For small examples or initial learning, it's very common to run Kani on just one source file.
4-
5-
The command line format for invoking Kani directly is the following:
6-
7-
```
8-
kani filename.rs [<kani-args>]*
9-
```
10-
11-
For example,
12-
13-
```
14-
kani example.rs
15-
```
16-
17-
runs Kani on all the proof harnesses from file `example.rs`.
18-
A proof harness is simply a function with the `#[kani::proof]` annotation.
19-
20-
## Common arguments
21-
22-
The most common `kani` arguments are the following:
23-
24-
* `--harness <name>`: By default, Kani checks all proof harnesses it finds. You
25-
can switch to checking a single harness using this flag.
26-
27-
* `--default-unwind <n>`: Set a global upper [loop
28-
unwinding](./tutorial-loop-unwinding.md) bound on all loops. This can force
29-
termination when CBMC tries to unwind loops indefinitely.
30-
31-
* `--output-format <regular|terse|old>`: By default (`regular`), Kani
32-
post-processes CBMC's output to produce more comprehensible results. In
33-
contrast, `terse` outputs only a summary of these results, and `old` forces
34-
Kani to emit the original output from CBMC.
35-
36-
* `--visualize`: Generates an HTML report in the local directory accessible
37-
through `report/html/index.html`. This report shows coverage information and
38-
provides traces (i.e., counterexamples) for each failure found by Kani.
39-
40-
Run `kani --help` to see a complete list of arguments.
3+
[See here](./usage.md#usage-on-a-single-crate)

docs/src/tool-comparison.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Property testing is often quite effective, but the engine can't fully prove the
1616
**Model checking** is similar to these techniques in how you use them, but it's non-random and exhaustive (though often only up to some bound on input or problem size).
1717
Thus, properties checked with a model checker are effectively proofs.
1818
Instead of naively trying all possible _concrete_ inputs (which could be infeasible and blow up exponentially), model checkers like Kani will cleverly encode program traces as _symbolic_ "[SAT](https://en.wikipedia.org/wiki/Boolean_satisfiability_problem)/[SMT](https://en.wikipedia.org/wiki/Satisfiability_modulo_theories)" problems, and hand them off to SAT/SMT solvers.
19-
Again, SAT/SMT solving is an [NP-complete](https://en.wikipedia.org/wiki/NP-completeness) problem, but most practical programs can be model- checked within milliseconds to seconds (with notable exceptions: you can easily try to reverse a cryptographic hash with a model checker, but good luck getting it to terminate!)
19+
SAT/SMT solving is an [NP-complete](https://en.wikipedia.org/wiki/NP-completeness) problem, but many practical programs can be model-checked within milliseconds to seconds (with notable exceptions: you can easily try to reverse a cryptographic hash with a model checker, but good luck getting it to terminate!)
2020

2121
Model checking allows you to prove non-trivial properties about programs, and check those proofs in roughly the same amount of time as a traditional test suite would take to run.
2222
The downside is many types of properties can quickly become "too large" to practically model-check, and so writing "proof harnesses" (very similar to property tests and fuzzer harnesses) requires some skill to understand why the solver is not terminating and fix the structure of the problem you're giving it so that it does.

docs/src/tutorial-real-code.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@ Sometimes the best place to start won't be your code, but the code that you depe
4040
If it's used by more projects that just yours, it will be valuable to more people, too!
4141

4242
3. Find well-tested code.
43-
Code structure changes to make code more unit-testable will make it more provable, too.
43+
When you make changes to improve the unit-testability of code, that also makes it more amenable to proof, too.
4444

4545
Here are some things to avoid, when starting out:
4646

4747
1. Lots of loops, or at least nested loops.
48-
As we saw in the last section, right now we often need to put upper bounds on these to make more limited claims.
48+
As we saw in the [tutorial](./tutorial-loop-unwinding.md), right now we often need to put upper bounds on loops to make more limited claims.
4949

5050
2. Inductive data structures.
5151
These are data structures with unbounded size (e.g., linked lists or trees.)
@@ -73,12 +73,21 @@ A first proof will likely start in the following form:
7373

7474
Running Kani on this simple starting point will help figure out:
7575

76-
1. What unexpected constraints might be needed on your inputs to avoid "expected" failures.
77-
2. Whether you're over-constrained. Check the coverage report using `--visualize`. Ideally you'd see 100% coverage, and if not, it's usually because now you've over-constrained the inputs.
76+
1. What unexpected constraints might be needed on your inputs (using `kani::assume`) to avoid "expected" failures.
77+
2. Whether you're over-constrained. Check the coverage report using `--visualize`. Ideally you'd see 100% coverage, and if not, it's usually because you've assumed too much (thus over-constraining the inputs).
7878
3. Whether Kani will support all the Rust features involved.
7979
4. Whether you've started with a tractable problem.
80-
(If the problem is initially intractable, try `--default-unwind 1` and see if you can follow the techniques in the previous section to put a bound on the problem.)
80+
(Remember to try setting `#[kani::unwind(1)]` to force early termination and work up from there.)
8181

82-
Once you've got something working, the next step is to prove more interesting properties than what Kani covers by default.
82+
Once you've got something working, the next step is to prove more interesting properties than just what Kani covers by default.
8383
You accomplish this by adding new assertions (not just in your harness, but also to the code being run).
8484
Even if a proof harness has no post-conditions being asserted directly, the assertions encountered along the way can be meaningful proof results by themselves.
85+
86+
87+
## Examples of the use of Kani
88+
89+
On the [Kani blog](https://model-checking.github.io/kani-verifier-blog/), we've documented worked examples of applying Kani:
90+
91+
1. [The `Rectangle` example of the Rust Book](https://model-checking.github.io/kani-verifier-blog/2022/05/04/announcing-the-kani-rust-verifier-project.html)
92+
2. [A Rust standard library CVE](https://model-checking.github.io/kani-verifier-blog/2022/06/01/using-the-kani-rust-verifier-on-a-rust-standard-library-cve.html)
93+
3. [Verifying a part of Firecracker](https://model-checking.github.io/kani-verifier-blog/2022/07/13/using-the-kani-rust-verifier-on-a-firecracker-example.html)

docs/src/undefined-behaviour.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ A non-exhaustive list of these, based on the non-exhaustive list from the [Rust
3535
* Calling a function with the wrong call ABI or unwinding from a function with the wrong unwind ABI.
3636
* Kani relies on `rustc` to check for this case.
3737
* Producing an invalid value, even in private fields and locals.
38-
* Kani provides a [mechanism](./tutorial-nondeterministic-variables.md#safe-nondeterministic-variables-for-custom-types) `is_valid()` which users can use to check validity of objects, but it does not currently apply to all types.
38+
* Kani [won't create invalid values](./tutorial-nondeterministic-variables.md) with `kani::any()` but it also won't complain if you `transmute` an invalid value to a Rust type (for example, a `0` to `NonZeroU32`).
3939
* Incorrect use of inline assembly.
4040
* Kani does not support inline assembly.
4141
* Using uninitialized memory.
@@ -46,5 +46,3 @@ Kani makes a best-effort attempt to detect some cases of UB:
4646
* Kani can detect invalid dereferences, but may not detect them in [place expression context](https://doc.rust-lang.org/reference/expressions.html#place-expressions-and-value-expressions).
4747
* Invoking undefined behavior via compiler intrinsics.
4848
* See [current support for compiler intrinsics](./rust-feature-support/intrinsics.md).
49-
* Producing an invalid value, even in private fields and locals.
50-
* Kani provides a [mechanism](./tutorial-nondeterministic-variables.md#safe-nondeterministic-variables-for-custom-types) `is_valid()` which users can use to check validity of objects, but it does not currently apply to all types.

docs/src/usage.md

Lines changed: 90 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,94 @@
1-
# Usage
1+
# Using Kani
22

33
At present, Kani can used in two ways:
4-
* [On a single file](./kani-single-file.md) with the `kani` command.
5-
* [On a package](./cargo-kani.md) with the `cargo-kani` command.
64

7-
Running [Kani on a single file](./kani-single-file.md) is quite useful for small
8-
examples or projects that don't use `cargo`.
5+
* [On a single crate](#usage-on-a-single-crate) with the `kani` command.
6+
* [On a Cargo package](#usage-on-a-package) with the `cargo kani` command.
97

10-
However, if you plan to integrate Kani in your projects, the recommended
11-
approach is to use [Kani on a package](./cargo-kani.md) because of its ability
12-
to handle external dependencies.
8+
If you plan to integrate Kani in your projects, the recommended approach is to use `cargo kani`.
9+
If you're already using cargo, this will handle dependencies automatically, and it can be configured (if needed) in `Cargo.toml`.
10+
But `kani` is useful for small examples/tests.
11+
12+
## Usage on a package
13+
14+
Kani is integrated with `cargo` and can be invoked from a package as follows:
15+
16+
```bash
17+
cargo kani [OPTIONS]
18+
```
19+
20+
This works like `cargo test` except that it will analyze all proof harnesses instead of running all test harnesses.
21+
22+
## Common command line flags
23+
24+
Common to both `kani` and `cargo kani` are many command-line flags:
25+
26+
* `--visualize`: Generates an HTML report showing coverage information and providing traces (i.e., counterexamples) for each failure found by Kani.
27+
28+
* `--tests`: Build in "[test mode](https://doc.rust-lang.org/rustc/tests/index.html)", i.e. with `cfg(test)` set and `dev-dependencies` available (when using `cargo kani`).
29+
30+
* `--harness <name>`: By default, Kani checks all proof harnesses it finds.
31+
You can switch to checking a single harness using this flag.
32+
33+
* `--default-unwind <n>`: Set a default global upper [loop unwinding](./tutorial-loop-unwinding.md) bound for proof harnesses.
34+
This can force termination when CBMC tries to unwind loops indefinitely.
35+
36+
Run `cargo kani --help` to see a complete list of arguments.
37+
38+
## Usage on a single crate
39+
40+
For small examples or initial learning, it's very common to run Kani on just one source file.
41+
The command line format for invoking Kani directly is the following:
42+
43+
```
44+
kani filename.rs [OPTIONS]
45+
```
46+
47+
This will build `filename.rs` and run all proof harnesses found within.
48+
49+
## Configuration in `Cargo.toml`
50+
51+
Users can add a default configuration to the `Cargo.toml` file for running harnesses in a package.
52+
Kani will extract any arguments from these sections:
53+
54+
* `[workspace.metadata.kani.flags]`
55+
* `[package.metadata.kani.flags]`
56+
57+
For example, if you want to set a default loop unwinding bound (when it's not otherwise specified), you can achieve this by adding the following lines to the package's `Cargo.toml`:
58+
59+
```toml
60+
[package.metadata.kani.flags]
61+
default-unwind = 1
62+
```
63+
64+
The options here are the same as on the command line (`cargo kani --help`), and flags (that is, command line arguments that don't take a value) are enabled by setting them to `true`.
65+
66+
## The build process
67+
68+
When Kani builds your code, it does two important things:
69+
70+
1. It sets `cfg(kani)`.
71+
2. It injects the `kani` crate.
72+
73+
A proof harness (which you can [learn more about in the tutorial](./kani-tutorial.md)), is a function annotated with `#[kani::proof]` much like a test is annotated with `#[test]`.
74+
But you may experience a similar problem using Kani as you would with `dev-dependencies`: if you try writing `#[kani::proof]` directly in your code, `cargo build` will fail because it doesn't know what the `kani` crate is.
75+
76+
This is why we recommend the same conventions as are used when writing tests in Rust: wrap your proof harnesses in `cfg(kani)` conditional compilation:
77+
78+
```rust
79+
#[cfg(kani)]
80+
mod verification {
81+
use super::*;
82+
83+
#[kani::proof]
84+
pub fn check_something() {
85+
// ....
86+
}
87+
}
88+
```
89+
90+
This will ensure that a normal build of your code will be completely unaffected by anything Kani-related.
91+
92+
This conditional compilation with `cfg(kani)` (as seen above) is still required for Kani proofs placed under `tests/`.
93+
When this code is built by `cargo test`, the `kani` crate is not available, and so it would otherwise cause build failures.
94+
(Whereas the use of `dev-dependencies` under `tests/` does not need to be gated with `cfg(test)` since that code is already only built when testing.)

0 commit comments

Comments
 (0)