Skip to content

Commit 90330b2

Browse files
authored
docs: add conc playback docs to getting started tutorial (rust-lang#1537)
* docs: add conc playback sub-section to getting started * refactor: change exe-trace name in Kani flags * refactor: initial change over to new flags * refactor: change exe_trace in Kani lib * more Kani lib name updates * update feature flag in docs * bunch more name changes * change det val to concrete val * fix wording * update arg desc * make output_filename_opt more clean * more renaming * more det renaming in kani lib * address some of Celina's comments * remove all the rename changes * some more updates * change tense from 'user' to 'you' * make setup section more clear * update doc structure to debug verif fails * turn options into bullets * add enable-unstable * add example * add to example * add mode description to args * add link to milestone
1 parent 04c5a74 commit 90330b2

File tree

5 files changed

+118
-4
lines changed

5 files changed

+118
-4
lines changed

docs/src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- [Building from source](./build-from-source.md)
66
- [Using Kani](./usage.md)
77
- [Verification results](./verification-results.md)
8+
- [Debugging verification failures](./debugging-verification-failures.md)
89

910
- [Tutorial](./kani-tutorial.md)
1011
- [First steps](./tutorial-first-steps.md)
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Debugging verification failures
2+
3+
When the result of a certain check comes back as a `FAILURE`,
4+
Kani offers different options to help debug:
5+
* `--concrete-playback`. This _experimental_ feature generates a Rust unit test case that plays back a failing
6+
proof harness using a concrete counterexample.
7+
* `--visualize`. This feature generates an HTML text-based trace that
8+
enumerates the execution steps leading to the check failure.
9+
10+
## Concrete playback
11+
12+
This section describes the concrete playback feature in more detail.
13+
14+
### Setup
15+
16+
The Kani library needs to be linked as a dev dependency to the crate you're trying to debug.
17+
This requires adding the following lines to your `Cargo.toml` file,
18+
which differ depending on what version of the Kani library you would like to use:
19+
* The latest version:
20+
```toml
21+
[dev-dependencies]
22+
kani = { git = "https://github.com/model-checking/kani", features = ["concrete_playback"] }
23+
```
24+
* A specific version of the Kani library (v0.9+) that's already downloaded:
25+
```toml
26+
[dev-dependencies]
27+
kani = { path = "{path_to_kani_root}/library/kani", features = ["concrete_playback"] }
28+
```
29+
30+
### Usage
31+
32+
In order to enable this feature, run Kani with the `--enable-unstable --concrete-playback=[print|inplace]` flag.
33+
After getting a verification failure, Kani will generate a Rust unit test case that plays back a failing
34+
proof harness with a concrete counterexample.
35+
The concrete playback modes mean the following:
36+
* `print`: Kani will just print the unit test to stdout.
37+
You will then need to copy this unit test into the same module as your proof harness.
38+
* `inplace`: Kani will automatically copy the unit test into your source code.
39+
Before running this mode, you might find it helpful to have your existing code committed to `git`.
40+
That way, you can easily remove the unit test with `git revert`.
41+
Note that Kani will not copy the unit test into your source code if it detects
42+
that the exact same test already exists.
43+
44+
After the unit test is in your source code, you can run it with `cargo test`.
45+
To debug it, there are a couple of options:
46+
* If you have certain IDEs, there are extensions (e.g., `rust-analyzer` for `VS Code`)
47+
that support UI elements like a `Run Test | Debug` button next to all unit tests.
48+
* Otherwise, you can debug the unit test on the command line.
49+
To do this, you first run `cargo test {unit_test_func_name}`.
50+
The output from this will have a line in the beginning like `Running unittests {files} ({binary})`.
51+
You can then debug the binary with tools like `rust-gdb` or `lldb`.
52+
53+
### Example
54+
55+
Running `kani --harness proof_harness --enable-unstable --concrete-playback=print` on the following source file:
56+
```rust
57+
#[kani::proof]
58+
fn proof_harness() {
59+
let a: u8 = kani::any();
60+
let b: u16 = kani::any();
61+
assert!(a / 2 * 2 == a &&
62+
b / 2 * 2 == b);
63+
}
64+
```
65+
yields this concrete playback Rust unit test:
66+
```rust
67+
#[test]
68+
fn kani_concrete_playback_proof_harness_16220658101615121791() {
69+
let concrete_vals: Vec<Vec<u8>> = vec![
70+
// 133
71+
vec![133],
72+
// 35207
73+
vec![135, 137],
74+
];
75+
kani::concrete_playback_run(concrete_vals, proof_harness);
76+
}
77+
```
78+
Here, `133` and `35207` are the concrete values that, when substituted for `a` and `b`,
79+
cause an assertion failure.
80+
`vec![135, 137]` is the byte array representation of `35207`.
81+
82+
### Common issues
83+
84+
* `error[E0425]: cannot find function x in this scope`:
85+
this is usually caused by having `#[cfg(kani)]` somewhere in the control flow path of the user's proof harness.
86+
To fix this, remove `#[cfg(kani)]` from those paths.
87+
88+
### Request for comments
89+
90+
This feature is experimental and is therefore subject to change.
91+
If you have ideas for improving the user experience of this feature,
92+
please add them to [this GitHub issue](https://github.com/model-checking/kani/issues/1536).
93+
We are tracking the existing feature requests in
94+
[this GitHub milestone](https://github.com/model-checking/kani/milestone/10).
95+
96+
### Limitations
97+
98+
* This feature does not generate unit tests for failing non-panic checks (e.g., UB checks).
99+
This is because checks would not trigger runtime errors during concrete playback.
100+
Kani generates warning messages for this.
101+
* This feature does not support generating unit tests for multiple assertion failures within the same harness.
102+
This limitation might be removed in the future.
103+
Kani generates warning messages for this.
104+
* This feature requires that you do not change your code or runtime configurations between when Kani generates the unit test and when you run it.
105+
For instance, if you linked with library A during unit test generation and library B during unit test play back,
106+
that might cause unintended errors in the unit test counterexample.
107+
Kani currently has no way to detect this issue.

docs/src/usage.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ This works like `cargo test` except that it will analyze all proof harnesses ins
2323

2424
Common to both `kani` and `cargo kani` are many command-line flags:
2525

26+
* `--concrete-playback=[print|inplace]`: _Experimental_, `--enable-unstable` feature that generates a Rust unit test case
27+
that plays back a failing proof harness using a concrete counterexample.
28+
If used with `print`, Kani will only print the unit test to stdout.
29+
If used with `inplace`, Kani will automatically add the unit test to the user's source code, next to the proof harness. For more detailed instructions, see the [debugging verification failures](./debugging-verification-failures.md) section.
30+
2631
* `--visualize`: Generates an HTML report showing coverage information and providing traces (i.e., counterexamples) for each failure found by Kani.
2732

2833
* `--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`).

docs/src/verification-results.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@ Check 4: success_example.assertion.4
3838
```
3939

4040
2. `FAILURE`: This indicates that the check failed (i.e., the property doesn't
41-
hold). In this case, you can examine a trace by re-running with the
42-
`--visualize` option. This generates an HTML report with the trace
43-
information.
41+
hold). In this case, please see the [debugging verification failures](./debugging-verification-failures.md)
42+
section for more help.
4443

4544
Example:
4645
```rust

kani-driver/src/args.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ pub struct KaniArgs {
4343
/// Generate visualizer report to <target-dir>/report/html/index.html
4444
#[structopt(long)]
4545
pub visualize: bool,
46-
/// Generate concrete playback unit test and either 1) just print it to stdout or 2) add it in-place to the source code.
46+
/// Generate concrete playback unit test.
47+
/// If value supplied is 'print', Kani prints the unit test to stdout.
48+
/// If value supplied is 'inplace', Kani automatically adds the unit test to your source code.
4749
/// This option does not work with `--output-format old`.
4850
#[structopt(
4951
long,

0 commit comments

Comments
 (0)