Skip to content

CBMC/JBMC --cover: only store traces with --trace to avoid memory exhaustion #5714

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions doc/cprover-manual/test-suite.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,11 @@ and outputs of interest for generating test suites.
To demonstrate the automatic test suite generation in CBMC, we call the
following command:

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

We'll describe those command line options one by one. The option `--cover mcdc`
specifies the code coverage criterion. There
specifies the code coverage criterion, and --show-test-suite requests that a
test suite be printed. There
are four conditional statements in the PID function: in lines 41,
44, 48, and 49. To satisfy MC/DC, the test suite has to meet
multiple requirements. For instance, each conditional statement needs to
Expand Down
2 changes: 1 addition & 1 deletion regression/cbmc-cover/branch-loop1/test.desc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CORE
main.c
--xml-ui --cover branch
--xml-ui --cover branch --show-test-suite
activate-multi-line-match
^EXIT=0$
^SIGNAL=0$
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CORE
main.c
--function fun --cover branch
--function fun --cover branch --show-test-suite
^\*\* 7 of 7 covered \(100.0%\)$
^Test suite:$
a=\(\(signed int \*\*\)NULL\)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CORE
main.c
--function fun --cover branch
--function fun --cover branch --show-test-suite
^\*\* 5 of 5 covered \(100\.0%\)$
^Test suite:$
^(tmp(\$\d+)?=[^,]*, a=\(\(signed int \*\)NULL\))|(a=\(\(signed int \*\)NULL\), tmp(\$\d+)?=[^,]*)$
Expand Down
7 changes: 5 additions & 2 deletions src/cbmc/cbmc_parse_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -726,8 +726,11 @@ int cbmc_parse_optionst::doit()
(void)verifier();
verifier.report();

c_test_input_generatort test_generator(ui_message_handler, options);
test_generator(verifier.get_traces());
if(options.get_bool_option("show-test-suite"))
{
c_test_input_generatort test_generator(ui_message_handler, options);
test_generator(verifier.get_traces());
}

return CPROVER_EXIT_SUCCESS;
}
Expand Down
11 changes: 8 additions & 3 deletions src/goto-checker/cover_goals_verifier_with_trace_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,14 @@ class cover_goals_verifier_with_trace_storaget : public goto_verifiert
while(incremental_goto_checker(properties).progress !=
incremental_goto_checkert::resultt::progresst::DONE)
{
// we've got a trace; store it and link it to the covered goals
message_building_error_trace(log);
(void)traces.insert_all(incremental_goto_checker.build_full_trace());
if(
options.get_bool_option("show-test-suite") ||
options.get_bool_option("trace"))
{
// we've got a trace; store it and link it to the covered goals
message_building_error_trace(log);
(void)traces.insert_all(incremental_goto_checker.build_full_trace());
}

++iterations;
}
Expand Down
13 changes: 11 additions & 2 deletions src/goto-checker/goto_trace_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ const goto_tracet &goto_trace_storaget::insert(goto_tracet &&trace)
emplace_result.second,
"cannot associate more than one error trace with property " +
id2string(last_step.property_id));

for(auto &step : traces.back().steps)
step.merge_ireps(merge_ireps);

return traces.back();
}

Expand All @@ -40,10 +44,14 @@ const goto_tracet &goto_trace_storaget::insert_all(goto_tracet &&trace)
{
property_id_to_trace_index.emplace(property_id, traces.size() - 1);
}

for(auto &step : traces.back().steps)
step.merge_ireps(merge_ireps);

return traces.back();
}

const std::vector<goto_tracet> &goto_trace_storaget::all() const
const std::list<goto_tracet> &goto_trace_storaget::all() const
{
return traces;
}
Expand All @@ -53,8 +61,9 @@ operator[](const irep_idt &property_id) const
{
const auto trace_found = property_id_to_trace_index.find(property_id);
PRECONDITION(trace_found != property_id_to_trace_index.end());
CHECK_RETURN(trace_found->second < traces.size());

return traces.at(trace_found->second);
return *(std::next(traces.begin(), trace_found->second));
}

const namespacet &goto_trace_storaget::get_namespace() const
Expand Down
11 changes: 9 additions & 2 deletions src/goto-checker/goto_trace_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ Author: Daniel Kroening, Peter Schrammel

#include <goto-programs/goto_trace.h>

#include <util/merge_irep.h>

#include <list>

class goto_trace_storaget
{
public:
Expand All @@ -28,7 +32,7 @@ class goto_trace_storaget
/// are mapped to the given trace.
const goto_tracet &insert_all(goto_tracet &&);

const std::vector<goto_tracet> &all() const;
const std::list<goto_tracet> &all() const;
const goto_tracet &operator[](const irep_idt &property_id) const;

const namespacet &get_namespace() const;
Expand All @@ -38,10 +42,13 @@ class goto_trace_storaget
const namespacet &ns;

/// stores the traces
std::vector<goto_tracet> traces;
std::list<goto_tracet> traces;

// maps property ID to index in traces
std::unordered_map<irep_idt, std::size_t> property_id_to_trace_index;

/// irep container for shared ireps
merge_irept merge_ireps;
};

#endif // CPROVER_GOTO_CHECKER_GOTO_TRACE_STORAGE_H
2 changes: 2 additions & 0 deletions src/goto-instrument/cover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ void parse_cover_options(const cmdlinet &cmdline, optionst &options)
cmdline.isset("cover-traces-must-terminate"));
options.set_option(
"cover-failed-assertions", cmdline.isset("cover-failed-assertions"));

options.set_option("show-test-suite", cmdline.isset("show-test-suite"));
}

/// Build data structures controlling coverage from command-line options.
Expand Down
7 changes: 5 additions & 2 deletions src/goto-instrument/cover.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,18 @@ class optionst;

#define OPT_COVER \
"(cover):" \
"(cover-failed-assertions)"
"(cover-failed-assertions)" \
"(show-test-suite)"

#define HELP_COVER \
" --cover CC create test-suite with coverage criterion " \
"CC\n" \
" --cover-failed-assertions do not stop coverage checking at failed " \
"assertions\n" \
" (this is the default for --cover " \
"assertions)\n"
"assertions)\n" \
" --show-test-suite print test suite for coverage criterion " \
"(requires --cover)"

enum class coverage_criteriont
{
Expand Down
15 changes: 15 additions & 0 deletions src/goto-programs/goto_trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Author: Daniel Kroening
#include <util/arith_tools.h>
#include <util/byte_operators.h>
#include <util/format_expr.h>
#include <util/merge_irep.h>
#include <util/range.h>
#include <util/string_utils.h>
#include <util/symbol.h>
Expand Down Expand Up @@ -133,6 +134,20 @@ void goto_trace_stept::output(

out << '\n';
}

void goto_trace_stept::merge_ireps(merge_irept &dest)
{
dest(cond_expr);
dest(full_lhs);
dest(full_lhs_value);

for(auto &io_arg : io_args)
dest(io_arg);

for(auto &function_arg : function_arguments)
dest(function_arg);
}

/// Returns the numeric representation of an expression, based on
/// options. The default is binary without a base-prefix. Setting
/// options.hex_representation to be true outputs hex format. Setting
Expand Down
6 changes: 6 additions & 0 deletions src/goto-programs/goto_trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ Date: July 2005

#include <goto-programs/goto_program.h>

class merge_irept;

/// Step of the trace of a GOTO program
///
/// A step is either:
Expand Down Expand Up @@ -162,6 +164,10 @@ class goto_trace_stept
full_lhs_value.make_nil();
cond_expr.make_nil();
}

/// Use \p dest to establish sharing among ireps.
/// \param [out] dest: irep storage container.
void merge_ireps(merge_irept &dest);
};

/// Trace of a GOTO program.
Expand Down