Skip to content

Commit 467ec66

Browse files
committed
goto-harness: create goto binary or C output
It is not always necessary or desirable to produce C output. An ability to produce goto binaries also avoids possible limitations of C and/or dump-c (such as goto-harness creating initialisers for structs with bit fields, which yield functions that take bit fields as parameters, which isn't possible in C). While at it, also clean up the help output to fix confusing language about goto binaries when the output was actually C code. Fixes: diffblue#5351
1 parent fac41f2 commit 467ec66

File tree

13 files changed

+79
-71
lines changed

13 files changed

+79
-71
lines changed

doc/architectural/goto-harness.md

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ $ goto-cc program.c -o program.gb
2020
# Run goto-harness to produce harness file
2121
$ goto-harness --harness-type call-function --harness-function-name generated_harness_test_function --function test_function program.gb harness.c
2222
# Run the checks targetting the generated harness
23-
$ cbmc --pointer-check harness.c --function generated_harness_test_function
23+
$ cbmc --pointer-check harness.c program.c --function generated_harness_test_function
2424
```
2525

2626
## Detailed Usage
@@ -32,11 +32,9 @@ without having any information about the program state.
3232
* The `memory-snapshot` harness, which loads an existing program state (in form
3333
of a JSON file) and selectively _havoc-ing_ some variables.
3434

35-
**NOTE**: Due to a [bug](https://github.com/diffblue/cbmc/issues/5351), the
36-
`memory-snapshot` harness is currently inoperable. We are working to fix this.
37-
38-
It is used similarly to how `goto-instrument` is used by modifying an existing
39-
GOTO binary, as produced by `goto-cc`.
35+
The harness generator can either produce the harness (i.e., the function
36+
environment) as C code, or a full GOTO binary. C code is generated when the
37+
output file name ends in ".c".
4038

4139
### The function call harness generator
4240

@@ -364,12 +362,6 @@ VERIFICATION SUCCESSFUL
364362

365363
## The memory snapshot harness
366364

367-
***NOTE:*** The memory snapshot harness is temporarily inoperable because of
368-
a bug that occured when we changed the implementation of `goto-harness` to
369-
produce C files instead of `goto` binaries. The bug is being tracked
370-
[here](https://github.com/diffblue/cbmc/issues/5351). We are sorry for the
371-
inconvenience, and hope to get it back to working properly soon.
372-
373365
The `function-call` harness is used in situations in which we want to analyze a
374366
function in an arbitrary environment. If we want to analyze a function starting
375367
from a _real_ program state, we can use the `memory-snapshot` harness instead.

regression/goto-harness/chain.sh

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,20 @@ cbmc=$3
88
is_windows=$4
99
entry_point='generated_entry_function'
1010

11+
shift 4
1112
name=${*:$#}
1213
name=${name%.c}
13-
args=${*:5:$#-5}
1414

1515
input_c_file="${name}.c"
1616
input_goto_binary="${name}.gb"
17-
harness_c_file="${name}-harness.c"
17+
if [[ "$1" == "harness.gb" ]]; then
18+
harness_file=$1
19+
shift
20+
else
21+
harness_file="${name}-harness.c"
22+
fi
23+
24+
args=${*:1:$#-1}
1825

1926

2027

@@ -25,16 +32,24 @@ else
2532
$goto_cc -o "$input_goto_binary" "$input_c_file"
2633
fi
2734

28-
if [ -e "$harness_c_file" ] ; then
29-
rm -f "$harness_c_file"
35+
if [ -e "$harness_file" ] ; then
36+
rm -f "$harness_file"
3037
fi
3138

3239
# `# some comment` is an inline comment - basically, cause bash to execute an empty command
3340
$cbmc --show-goto-functions "$input_goto_binary"
34-
$goto_harness "$input_goto_binary" "$harness_c_file" --harness-function-name $entry_point ${args}
35-
$cbmc --show-goto-functions "$harness_c_file"
36-
$cbmc --function $entry_point "$input_c_file" "$harness_c_file" \
41+
$goto_harness "$input_goto_binary" "$harness_file" --harness-function-name $entry_point ${args}
42+
$cbmc --show-goto-functions "$harness_file"
43+
if [[ "${harness_file}" == "harness.gb" ]];then
44+
$cbmc --function $entry_point "$harness_file" \
45+
--pointer-check `# because we want to see out of bounds errors` \
46+
--unwind 11 `# with the way we set up arrays symex can't figure out loop bounds automatically` \
47+
--unwinding-assertions `# we want to make sure we don't accidentally pass tests because we didn't unwind enough` \
48+
# cbmc args end
49+
else
50+
$cbmc --function $entry_point "$input_c_file" "$harness_file" \
3751
--pointer-check `# because we want to see out of bounds errors` \
3852
--unwind 11 `# with the way we set up arrays symex can't figure out loop bounds automatically` \
3953
--unwinding-assertions `# we want to make sure we don't accidentally pass tests because we didn't unwind enough` \
4054
# cbmc args end
55+
fi
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
KNOWNBUG
1+
CORE
22
main.c
3-
--harness-type initialise-with-memory-snapshot --memory-snapshot ../load-snapshot-json-snapshots/global-int-x-y-snapshot.json --initial-goto-location main:7 --havoc-variables y
3+
harness.gb --harness-type initialise-with-memory-snapshot --memory-snapshot ../load-snapshot-json-snapshots/global-int-x-y-snapshot.json --initial-goto-location main:7 --havoc-variables y
44
^\[main.assertion.1\] line \d+ assertion y \+ 2 > y: FAILURE$
55
^\[main.assertion.2\] line \d+ assertion 0: FAILURE$
66
^EXIT=10$
77
^SIGNAL=0$
88
--
99
^warning: ignoring
10-
--
11-
More information can be found in github#5351.
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
KNOWNBUG
1+
CORE
22
main.c
3-
--harness-type initialise-with-memory-snapshot --memory-snapshot ../load-snapshot-json-snapshots/global-int-x-1-snapshot.json --initial-source-location main.c:6 --havoc-variables x
3+
harness.gb --harness-type initialise-with-memory-snapshot --memory-snapshot ../load-snapshot-json-snapshots/global-int-x-1-snapshot.json --initial-source-location main.c:6 --havoc-variables x
44
^EXIT=10$
55
^SIGNAL=0$
66
\[main.assertion.1\] line [0-9]+ assertion x == 1: SUCCESS
77
\[main.assertion.2\] line [0-9]+ assertion x == 2: FAILURE
88
\[main.assertion.3\] line [0-9]+ assertion x == 3: FAILURE
99
--
1010
^warning: ignoring
11-
--
12-
More information can be found in github#5351.

regression/goto-harness/havoc-global-struct/test.desc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
KNOWNBUG
1+
CORE
22
main.c
3-
--harness-type initialise-with-memory-snapshot --memory-snapshot ../load-snapshot-json-snapshots/global-struct-snapshot.json --initial-goto-location main:3 --havoc-variables simple
3+
harness.gb --harness-type initialise-with-memory-snapshot --memory-snapshot ../load-snapshot-json-snapshots/global-struct-snapshot.json --initial-goto-location main:3 --havoc-variables simple
44
^EXIT=10$
55
^SIGNAL=0$
66
^\[main.assertion.1\] line \d+ assertion simple.j > simple.i: FAILURE$

regression/goto-harness/load-snapshot-recursive-static-global-int-01/test.desc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
KNOWNBUG
1+
CORE
22
main.c
3-
--harness-type initialise-with-memory-snapshot --memory-snapshot ../load-snapshot-json-snapshots/global-int-x-1-snapshot.json --initial-goto-location main:1
3+
harness.gb --harness-type initialise-with-memory-snapshot --memory-snapshot ../load-snapshot-json-snapshots/global-int-x-1-snapshot.json --initial-goto-location main:1
44
^EXIT=0$
55
^SIGNAL=0$
66
VERIFICATION SUCCESSFUL

regression/goto-harness/load-snapshot-static-global-array-01/test.desc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
KNOWNBUG
1+
CORE
22
main.c
3-
--harness-type initialise-with-memory-snapshot --memory-snapshot snapshot.json --initial-goto-location main:0
3+
harness.gb --harness-type initialise-with-memory-snapshot --memory-snapshot snapshot.json --initial-goto-location main:0
44
^EXIT=0$
55
^SIGNAL=0$
66
VERIFICATION SUCCESSFUL
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
KNOWNBUG
1+
CORE
22
main.c
3-
--harness-type initialise-with-memory-snapshot --memory-snapshot ../load-snapshot-json-snapshots/global-int-x-1-snapshot.json --initial-goto-location main:0
3+
harness.gb --harness-type initialise-with-memory-snapshot --memory-snapshot ../load-snapshot-json-snapshots/global-int-x-1-snapshot.json --initial-goto-location main:0
44
^EXIT=0$
55
^SIGNAL=0$
66
VERIFICATION SUCCESSFUL
77
--
88
^warning: ignoring
9-
--
10-
More information can be found in github#5351.
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
KNOWNBUG
1+
CORE
22
main.c
3-
--harness-type initialise-with-memory-snapshot --memory-snapshot ../load-snapshot-json-snapshots/global-int-x-1-snapshot.json --initial-goto-location main:0
3+
harness.gb --harness-type initialise-with-memory-snapshot --memory-snapshot ../load-snapshot-json-snapshots/global-int-x-1-snapshot.json --initial-goto-location main:0
44
^EXIT=10$
55
^SIGNAL=0$
66
\[main.assertion.1\] line [0-9]+ assertion x == 1: SUCCESS
77
\[main.assertion.2\] line [0-9]+ assertion y == 1: FAILURE
88
--
99
^warning: ignoring
10-
--
11-
More information can be found in github#5351.
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
KNOWNBUG
1+
CORE
22
main.c
3-
--harness-type initialise-with-memory-snapshot --memory-snapshot ../load-snapshot-json-snapshots/global-int-x-1-snapshot.json --initial-goto-location main:0
3+
harness.gb --harness-type initialise-with-memory-snapshot --memory-snapshot ../load-snapshot-json-snapshots/global-int-x-1-snapshot.json --initial-goto-location main:0
44
^EXIT=0$
55
^SIGNAL=0$
66
VERIFICATION SUCCESSFUL
77
--
88
^warning: ignoring
9-
--
10-
More information can be found in github#5351.
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
KNOWNBUG
1+
CORE
22
main.c
3-
--harness-type initialise-with-memory-snapshot --memory-snapshot ../load-snapshot-json-snapshots/global-int-x-1-snapshot.json --initial-goto-location main:1
3+
harness.gb --harness-type initialise-with-memory-snapshot --memory-snapshot ../load-snapshot-json-snapshots/global-int-x-1-snapshot.json --initial-goto-location main:1
44
^EXIT=0$
55
^SIGNAL=0$
66
VERIFICATION SUCCESSFUL
77
--
88
^warning: ignoring
9-
--
10-
More information can be found in github#5351.

regression/goto-harness/load-snapshot-static-global-pointer-01/test.desc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
KNOWNBUG
1+
CORE
22
main.c
3-
--harness-type initialise-with-memory-snapshot --memory-snapshot snapshot.json --initial-goto-location main:0
3+
harness.gb --harness-type initialise-with-memory-snapshot --memory-snapshot snapshot.json --initial-goto-location main:0
44
^EXIT=0$
55
^SIGNAL=0$
66
VERIFICATION SUCCESSFUL

src/goto-harness/goto_harness_parse_options.cpp

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,21 @@ Author: Diffblue Ltd.
1515
#include <unordered_set>
1616
#include <utility>
1717

18-
#include <goto-instrument/dump_c.h>
19-
#include <goto-programs/goto_convert.h>
20-
#include <goto-programs/goto_model.h>
21-
#include <goto-programs/read_goto_binary.h>
22-
#include <goto-programs/show_symbol_table.h>
23-
#include <goto-programs/write_goto_binary.h>
24-
#include <langapi/mode.h>
2518
#include <util/config.h>
2619
#include <util/exception_utils.h>
2720
#include <util/exit_codes.h>
2821
#include <util/expr_iterator.h>
2922
#include <util/invariant.h>
23+
#include <util/suffix.h>
3024
#include <util/version.h>
3125

26+
#include <goto-instrument/dump_c.h>
27+
#include <goto-programs/goto_convert.h>
28+
#include <goto-programs/goto_model.h>
29+
#include <goto-programs/read_goto_binary.h>
30+
#include <goto-programs/show_symbol_table.h>
31+
#include <goto-programs/write_goto_binary.h>
32+
3233
#include "function_call_harness_generator.h"
3334
#include "goto_harness_generator_factory.h"
3435
#include "memory_snapshot_harness_generator.h"
@@ -145,15 +146,23 @@ int goto_harness_parse_optionst::doit()
145146
harness_generator->generate(
146147
goto_model, got_harness_config.harness_function_name);
147148

148-
filter_goto_model(goto_model, goto_model_without_harness_symbols);
149-
auto harness_out = std::ofstream{got_harness_config.out_file};
150-
dump_c(
151-
goto_model.goto_functions,
152-
true,
153-
true,
154-
false,
155-
namespacet{goto_model.get_symbol_table()},
156-
harness_out);
149+
if(!has_suffix(got_harness_config.out_file, ".c"))
150+
{
151+
write_goto_binary(
152+
got_harness_config.out_file, goto_model, log.get_message_handler());
153+
}
154+
else
155+
{
156+
filter_goto_model(goto_model, goto_model_without_harness_symbols);
157+
auto harness_out = std::ofstream{got_harness_config.out_file};
158+
dump_c(
159+
goto_model.goto_functions,
160+
true,
161+
true,
162+
false,
163+
namespacet{goto_model.get_symbol_table()},
164+
harness_out);
165+
}
157166

158167
return CPROVER_EXIT_SUCCESS;
159168
}
@@ -174,8 +183,12 @@ void goto_harness_parse_optionst::help()
174183
<< " goto-harness <in> <out> --harness-function-name <name> --harness-type "
175184
"<harness-type> [harness options]\n"
176185
<< "\n"
177-
<< "<in> goto binaries to read from\n"
178-
<< "<out> C file to write the harness to\n"
186+
<< "<in> goto binary to read from\n"
187+
<< "<out> file to write the harness to\n"
188+
<< " the harness is printed as C code, if <out> "
189+
"has a .c suffix,\n"
190+
" else a goto binary including the harness is "
191+
"generated\n"
179192
<< "--harness-function-name the name of the harness function to "
180193
"generate\n"
181194
<< "--harness-type one of the harness types listed below\n"
@@ -205,9 +218,9 @@ goto_harness_parse_optionst::handle_common_options()
205218
{
206219
help();
207220
throw invalid_command_line_argument_exceptiont{
208-
"need to specify both input and output goto binary file names (may be "
221+
"need to specify both input and output file names (may be "
209222
"the same)",
210-
"<in goto binary> <out goto binary>"};
223+
"<in goto binary> <output C file or goto binary>"};
211224
}
212225

213226
goto_harness_config.in_file = cmdline.args[0];

0 commit comments

Comments
 (0)