Skip to content

Commit 4820ec3

Browse files
authored
Merge pull request #5714 from tautschnig/cover-trace
CBMC/JBMC --cover: only store traces with --trace to avoid memory exhaustion
2 parents 37d6328 + 87e8440 commit 4820ec3

File tree

12 files changed

+67
-16
lines changed

12 files changed

+67
-16
lines changed

doc/cprover-manual/test-suite.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,11 @@ and outputs of interest for generating test suites.
128128
To demonstrate the automatic test suite generation in CBMC, we call the
129129
following command:
130130

131-
cbmc pid.c --cover mcdc --unwind 6 --xml-ui
131+
cbmc pid.c --cover mcdc --show-test-suite --unwind 6 --xml-ui
132132

133133
We'll describe those command line options one by one. The option `--cover mcdc`
134-
specifies the code coverage criterion. There
134+
specifies the code coverage criterion, and --show-test-suite requests that a
135+
test suite be printed. There
135136
are four conditional statements in the PID function: in lines 41,
136137
44, 48, and 49. To satisfy MC/DC, the test suite has to meet
137138
multiple requirements. For instance, each conditional statement needs to

regression/cbmc-cover/branch-loop1/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CORE
22
main.c
3-
--xml-ui --cover branch
3+
--xml-ui --cover branch --show-test-suite
44
activate-multi-line-match
55
^EXIT=0$
66
^SIGNAL=0$

regression/cbmc-cover/pointer-function-parameters-2/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CORE
22
main.c
3-
--function fun --cover branch
3+
--function fun --cover branch --show-test-suite
44
^\*\* 7 of 7 covered \(100.0%\)$
55
^Test suite:$
66
a=\(\(signed int \*\*\)NULL\)

regression/cbmc-cover/pointer-function-parameters/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CORE
22
main.c
3-
--function fun --cover branch
3+
--function fun --cover branch --show-test-suite
44
^\*\* 5 of 5 covered \(100\.0%\)$
55
^Test suite:$
66
^(tmp(\$\d+)?=[^,]*, a=\(\(signed int \*\)NULL\))|(a=\(\(signed int \*\)NULL\), tmp(\$\d+)?=[^,]*)$

src/cbmc/cbmc_parse_options.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -726,8 +726,11 @@ int cbmc_parse_optionst::doit()
726726
(void)verifier();
727727
verifier.report();
728728

729-
c_test_input_generatort test_generator(ui_message_handler, options);
730-
test_generator(verifier.get_traces());
729+
if(options.get_bool_option("show-test-suite"))
730+
{
731+
c_test_input_generatort test_generator(ui_message_handler, options);
732+
test_generator(verifier.get_traces());
733+
}
731734

732735
return CPROVER_EXIT_SUCCESS;
733736
}

src/goto-checker/cover_goals_verifier_with_trace_storage.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,14 @@ class cover_goals_verifier_with_trace_storaget : public goto_verifiert
4141
while(incremental_goto_checker(properties).progress !=
4242
incremental_goto_checkert::resultt::progresst::DONE)
4343
{
44-
// we've got a trace; store it and link it to the covered goals
45-
message_building_error_trace(log);
46-
(void)traces.insert_all(incremental_goto_checker.build_full_trace());
44+
if(
45+
options.get_bool_option("show-test-suite") ||
46+
options.get_bool_option("trace"))
47+
{
48+
// we've got a trace; store it and link it to the covered goals
49+
message_building_error_trace(log);
50+
(void)traces.insert_all(incremental_goto_checker.build_full_trace());
51+
}
4752

4853
++iterations;
4954
}

src/goto-checker/goto_trace_storage.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ const goto_tracet &goto_trace_storaget::insert(goto_tracet &&trace)
2727
emplace_result.second,
2828
"cannot associate more than one error trace with property " +
2929
id2string(last_step.property_id));
30+
31+
for(auto &step : traces.back().steps)
32+
step.merge_ireps(merge_ireps);
33+
3034
return traces.back();
3135
}
3236

@@ -40,10 +44,14 @@ const goto_tracet &goto_trace_storaget::insert_all(goto_tracet &&trace)
4044
{
4145
property_id_to_trace_index.emplace(property_id, traces.size() - 1);
4246
}
47+
48+
for(auto &step : traces.back().steps)
49+
step.merge_ireps(merge_ireps);
50+
4351
return traces.back();
4452
}
4553

46-
const std::vector<goto_tracet> &goto_trace_storaget::all() const
54+
const std::list<goto_tracet> &goto_trace_storaget::all() const
4755
{
4856
return traces;
4957
}
@@ -53,8 +61,9 @@ operator[](const irep_idt &property_id) const
5361
{
5462
const auto trace_found = property_id_to_trace_index.find(property_id);
5563
PRECONDITION(trace_found != property_id_to_trace_index.end());
64+
CHECK_RETURN(trace_found->second < traces.size());
5665

57-
return traces.at(trace_found->second);
66+
return *(std::next(traces.begin(), trace_found->second));
5867
}
5968

6069
const namespacet &goto_trace_storaget::get_namespace() const

src/goto-checker/goto_trace_storage.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ Author: Daniel Kroening, Peter Schrammel
1414

1515
#include <goto-programs/goto_trace.h>
1616

17+
#include <util/merge_irep.h>
18+
19+
#include <list>
20+
1721
class goto_trace_storaget
1822
{
1923
public:
@@ -28,7 +32,7 @@ class goto_trace_storaget
2832
/// are mapped to the given trace.
2933
const goto_tracet &insert_all(goto_tracet &&);
3034

31-
const std::vector<goto_tracet> &all() const;
35+
const std::list<goto_tracet> &all() const;
3236
const goto_tracet &operator[](const irep_idt &property_id) const;
3337

3438
const namespacet &get_namespace() const;
@@ -38,10 +42,13 @@ class goto_trace_storaget
3842
const namespacet &ns;
3943

4044
/// stores the traces
41-
std::vector<goto_tracet> traces;
45+
std::list<goto_tracet> traces;
4246

4347
// maps property ID to index in traces
4448
std::unordered_map<irep_idt, std::size_t> property_id_to_trace_index;
49+
50+
/// irep container for shared ireps
51+
merge_irept merge_ireps;
4552
};
4653

4754
#endif // CPROVER_GOTO_CHECKER_GOTO_TRACE_STORAGE_H

src/goto-instrument/cover.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ void parse_cover_options(const cmdlinet &cmdline, optionst &options)
166166
cmdline.isset("cover-traces-must-terminate"));
167167
options.set_option(
168168
"cover-failed-assertions", cmdline.isset("cover-failed-assertions"));
169+
170+
options.set_option("show-test-suite", cmdline.isset("show-test-suite"));
169171
}
170172

171173
/// Build data structures controlling coverage from command-line options.

src/goto-instrument/cover.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,18 @@ class optionst;
2424

2525
#define OPT_COVER \
2626
"(cover):" \
27-
"(cover-failed-assertions)"
27+
"(cover-failed-assertions)" \
28+
"(show-test-suite)"
2829

2930
#define HELP_COVER \
3031
" --cover CC create test-suite with coverage criterion " \
3132
"CC\n" \
3233
" --cover-failed-assertions do not stop coverage checking at failed " \
3334
"assertions\n" \
3435
" (this is the default for --cover " \
35-
"assertions)\n"
36+
"assertions)\n" \
37+
" --show-test-suite print test suite for coverage criterion " \
38+
"(requires --cover)"
3639

3740
enum class coverage_criteriont
3841
{

0 commit comments

Comments
 (0)