@@ -13,9 +13,10 @@ having to manually construct an appropriate environment.
13
13
14
14
We have two types of harnesses we can generate for now:
15
15
16
- * The ` memory-snapshot ` harness. TODO: Daniel can document this.
17
16
* The ` function-call ` harness, which automatically synthesises an environment
18
17
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.
19
20
20
21
It is used similarly to how ` goto-instrument ` is used by modifying an existing
21
22
GOTO binary, as produced by ` goto-cc ` .
@@ -309,4 +310,103 @@ main.c function function
309
310
310
311
** 0 of 1 failed (1 iterations)
311
312
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 to analyse a function
319
+ starting from a _real_ program state, we can call the `memory-snapshot` harness
320
+ 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`. Most commonly, the _location number_ is the instruction
331
+ of the break-point used to extract the program state for the memory snapshot.
332
+
333
+ Say we want to check the assertion in the following code:
334
+
335
+ ```C
336
+ // main.c
337
+ #include <assert.h>
338
+
339
+ unsigned int x;
340
+ unsigned int y;
341
+
342
+ unsigned int nondet_int() {
343
+ unsigned int z;
344
+ return z;
345
+ }
346
+
347
+ void checkpoint() {}
348
+
349
+ unsigned int complex_function_which_returns_one() {
350
+ unsigned int i = 0;
351
+ while(++i < 1000001) {
352
+ if(nondet_int() && ((i & 1) == 1))
353
+ break;
354
+ }
355
+ return i & 1;
356
+ }
357
+
358
+ void fill_array(unsigned int* arr, unsigned int size) {
359
+ for (unsigned int i = 0; i < size; i++)
360
+ arr[i]=nondet_int();
361
+ }
362
+
363
+ unsigned int array_sum(unsigned int* arr, unsigned int size) {
364
+ unsigned int sum = 0;
365
+ for (unsigned int i = 0; i < size; i++)
366
+ sum += arr[i];
367
+ return sum;
368
+ }
369
+
370
+ const unsigned int array_size = 100000;
371
+
372
+ int main() {
373
+ x = complex_function_which_returns_one();
374
+ unsigned int large_array[array_size];
375
+ fill_array(large_array, array_size);
376
+ y = array_sum(large_array, array_size);
377
+ checkpoint();
378
+ assert(y + 2 > x);
379
+ return 0;
380
+ }
381
+ ```
382
+
383
+ But are not particularly interested in analysing the complex function, since we
384
+ trust that its implementation is correct. Hence we run the above program
385
+ stopping after the assignments to ` x ` and ` x ` and storing the program state,
386
+ e.g. using the ` memory-analyzer ` , in a JSON file ` snapshot.json ` . Then run the
387
+ harness and verify the assertion with:
388
+
389
+ ```
390
+ $ goto-cc -o main.gb main.c
391
+ $ goto-harness \
392
+ --harness-function-name harness \
393
+ --harness-type initialise-with-memory-snapshot \
394
+ --memory-snapshot snapshot.json \
395
+ --initial-location checkpoint \
396
+ --havoc-variables x \
397
+ main.gb main-mod.gb
398
+ $ cbmc --function harness main-mod.gb
399
+ ```
400
+
401
+ This will result in:
402
+
403
+ ```
404
+ [...]
405
+
406
+ ** Results:
407
+ main.c function main
408
+ [main.assertion.1] line 42 assertion y + 2 > x: SUCCESS
409
+
410
+ ** 0 of 1 failed (1 iterations)
411
+ VERIFICATION SUCCESSFUL
412
+ ```
0 commit comments