Skip to content

Commit 2240eb9

Browse files
Petr BauchPetr Bauch
Petr Bauch
authored and
Petr Bauch
committed
Add cprover manual entry
Covering memory-snapshot harness, but not the memory analyzer.
1 parent b1e8a7c commit 2240eb9

File tree

1 file changed

+101
-2
lines changed

1 file changed

+101
-2
lines changed

doc/cprover-manual/goto-harness.md

Lines changed: 101 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ having to manually construct an appropriate environment.
1313

1414
We have two types of harnesses we can generate for now:
1515

16-
* The `memory-snapshot` harness. TODO: Daniel can document this.
1716
* The `function-call` harness, which automatically synthesises an environment
1817
without having any information about the program state.
18+
* The `memory-snapshot` harness, which loads an existing program state (in form
19+
of a JSON file) and selectively _havoc-ing_ some variables.
1920

2021
It is used similarly to how `goto-instrument` is used by modifying an existing
2122
GOTO binary, as produced by `goto-cc`.
@@ -309,4 +310,102 @@ main.c function function
309310

310311
** 0 of 1 failed (1 iterations)
311312
VERIFICATION SUCCESSFUL
312-
```
313+
```
314+
315+
### The memory snapshot harness
316+
317+
The `function-call` harness is used in situations in which we want the analysed
318+
function to work in arbitrary environment. If we want a more restricted
319+
environment or if we have an executable program in which our function will be
320+
called, we can call the `memory-snapshot` harness instead.
321+
322+
Furthermore, the program state of interest may be taken at a particular location
323+
within a function. In that case we do not want the harness to instrument the
324+
whole function but rather to allow starting the execution from a specific
325+
initial location (specified via `--initial-location func[:<n>]`). Note that the
326+
initial location does not have to be the first instruction of a function: we can
327+
also specify the _location number_ `n` to set the initial location inside our
328+
function. The _location numbers_ do not have to coincide with the lines of the
329+
program code. To find the _location number_ run CBMC with
330+
`--show-goto-functions`.
331+
332+
Say we want to check the assertion in the following code:
333+
334+
```C
335+
// main.c
336+
#include <assert.h>
337+
338+
unsigned int x;
339+
unsigned int y;
340+
341+
unsigned int nondet_int() {
342+
unsigned int z;
343+
return z;
344+
}
345+
346+
void checkpoint() {}
347+
348+
unsigned int complex_function_which_returns_one() {
349+
unsigned int i = 0;
350+
while(++i < 1000001) {
351+
if(nondet_int() && ((i & 1) == 1))
352+
break;
353+
}
354+
return i & 1;
355+
}
356+
357+
void fill_array(unsigned int* arr, unsigned int size) {
358+
for (unsigned int i = 0; i < size; i++)
359+
arr[i]=nondet_int();
360+
}
361+
362+
unsigned int array_sum(unsigned int* arr, unsigned int size) {
363+
unsigned int sum = 0;
364+
for (unsigned int i = 0; i < size; i++)
365+
sum += arr[i];
366+
return sum;
367+
}
368+
369+
const unsigned int array_size = 100000;
370+
371+
int main() {
372+
x = complex_function_which_returns_one();
373+
unsigned int large_array[array_size];
374+
fill_array(large_array, array_size);
375+
y = array_sum(large_array, array_size);
376+
checkpoint();
377+
assert(y + 2 > x);
378+
return 0;
379+
}
380+
```
381+
382+
But are not particularly interested in analysing the complex function, since we
383+
trust that its implementation is correct. Hence we run the above program
384+
stopping after the assignments to `x` and `x` and storing the program state,
385+
e.g. using the `memory-analyzer`, in a JSON file `snapshot.json`. Then run the
386+
harness and verify the assertion with:
387+
388+
```
389+
$ goto-cc -o main.gb main.c
390+
$ goto-harness \
391+
--harness-function-name harness \
392+
--harness-type initialise-with-memory-snapshot \
393+
--memory-snapshot snapshot.json \
394+
--initial-location checkpoint \
395+
--havoc-variables x \
396+
main.gb main-mod.gb
397+
$ cbmc --function harness main-mod.gb
398+
```
399+
400+
This will result in:
401+
402+
```
403+
[...]
404+
405+
** Results:
406+
main.c function main
407+
[main.assertion.1] line 42 assertion y + 2 > x: SUCCESS
408+
409+
** 0 of 1 failed (1 iterations)
410+
VERIFICATION SUCCESSFUL
411+
```

0 commit comments

Comments
 (0)