Skip to content

Single-path symex checker [blocks: #3976] #3969

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
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
37 changes: 37 additions & 0 deletions jbmc/src/java_bytecode/java_single_path_symex_checker.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*******************************************************************\

Module: Goto Checker using Single Path Symbolic Execution for Java

Author: Daniel Kroening, Peter Schrammel

\*******************************************************************/

/// \file
/// Goto Checker using Single Path Symbolic Execution for Java

#ifndef CPROVER_JAVA_BYTECODE_JAVA_SINGLE_PATH_SYMEX_CHECKER_H
#define CPROVER_JAVA_BYTECODE_JAVA_SINGLE_PATH_SYMEX_CHECKER_H

#include <goto-checker/single_path_symex_checker.h>

#include "java_bmc_util.h"

class java_single_path_symex_checkert : public single_path_symex_checkert
{
public:
java_single_path_symex_checkert(
const optionst &options,
ui_message_handlert &ui_message_handler,
abstract_goto_modelt &goto_model)
: single_path_symex_checkert(options, ui_message_handler, goto_model)
{
}

void setup_symex(symex_bmct &symex) override
{
single_path_symex_checkert::setup_symex(symex);
java_setup_symex(options, goto_model, symex);
}
};

#endif // CPROVER_JAVA_BYTECODE_JAVA_SINGLE_PATH_SYMEX_CHECKER_H
38 changes: 38 additions & 0 deletions jbmc/src/java_bytecode/java_single_path_symex_only_checker.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*******************************************************************\

Module: Goto Checker using Single Path Symbolic Execution for Java

Author: Daniel Kroening, Peter Schrammel

\*******************************************************************/

/// \file
/// Goto Checker using Single Path Symbolic Execution for Java

#ifndef CPROVER_JAVA_BYTECODE_JAVA_SINGLE_PATH_SYMEX_ONLY_CHECKER_H
#define CPROVER_JAVA_BYTECODE_JAVA_SINGLE_PATH_SYMEX_ONLY_CHECKER_H

#include <goto-checker/single_path_symex_only_checker.h>

#include "java_bmc_util.h"

class java_single_path_symex_only_checkert
: public single_path_symex_only_checkert
{
public:
java_single_path_symex_only_checkert(
const optionst &options,
ui_message_handlert &ui_message_handler,
abstract_goto_modelt &goto_model)
: single_path_symex_only_checkert(options, ui_message_handler, goto_model)
{
}

void setup_symex(symex_bmct &symex) override
{
single_path_symex_only_checkert::setup_symex(symex);
java_setup_symex(options, goto_model, symex);
}
};

#endif // CPROVER_JAVA_BYTECODE_JAVA_SINGLE_PATH_SYMEX_ONLY_CHECKER_H
61 changes: 48 additions & 13 deletions jbmc/src/jbmc/jbmc_parse_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ Author: Daniel Kroening, [email protected]
#include <java_bytecode/java_enum_static_init_unwind_handler.h>
#include <java_bytecode/java_multi_path_symex_checker.h>
#include <java_bytecode/java_multi_path_symex_only_checker.h>
#include <java_bytecode/java_single_path_symex_checker.h>
#include <java_bytecode/java_single_path_symex_only_checker.h>
#include <java_bytecode/remove_exceptions.h>
#include <java_bytecode/remove_instanceof.h>
#include <java_bytecode/remove_java_new.h>
Expand Down Expand Up @@ -559,46 +561,79 @@ int jbmc_parse_optionst::doit()
options.get_bool_option("program-only") ||
options.get_bool_option("show-vcc"))
{
if(!options.get_bool_option("paths"))
if(options.get_bool_option("paths"))
{
all_properties_verifiert<java_single_path_symex_only_checkert> verifier(
options, ui_message_handler, goto_model);
(void)verifier();
}
else
{
all_properties_verifiert<java_multi_path_symex_only_checkert> verifier(
options, ui_message_handler, goto_model);
(void)verifier();
return CPROVER_EXIT_SUCCESS;
}

return CPROVER_EXIT_SUCCESS;
}

if(
options.get_bool_option("dimacs") ||
!options.get_option("outfile").empty())
{
if(!options.get_bool_option("paths"))
if(options.get_bool_option("paths"))
{
stop_on_fail_verifiert<java_single_path_symex_checkert> verifier(
options, ui_message_handler, goto_model);
(void)verifier();
}
else
{
stop_on_fail_verifiert<multi_path_symex_checkert> verifier(
stop_on_fail_verifiert<java_multi_path_symex_checkert> verifier(
options, ui_message_handler, goto_model);
(void)verifier();
return CPROVER_EXIT_SUCCESS;
}

return CPROVER_EXIT_SUCCESS;
}

std::unique_ptr<goto_verifiert> verifier = nullptr;

if(
!options.get_bool_option("paths") && !options.is_set("cover") &&
!options.get_bool_option("dimacs") &&
!options.is_set("cover") && !options.get_bool_option("dimacs") &&
options.get_option("outfile").empty())
{
if(options.get_bool_option("stop-on-fail"))
{
verifier = util_make_unique<
stop_on_fail_verifiert<java_multi_path_symex_checkert>>(
options, ui_message_handler, goto_model);
if(options.get_bool_option("paths"))
{
verifier = util_make_unique<
stop_on_fail_verifiert<java_single_path_symex_checkert>>(
options, ui_message_handler, goto_model);
}
else
{
verifier = util_make_unique<
stop_on_fail_verifiert<java_multi_path_symex_checkert>>(
options, ui_message_handler, goto_model);
}
}
else
{
verifier = util_make_unique<all_properties_verifier_with_trace_storaget<
java_multi_path_symex_checkert>>(
options, ui_message_handler, goto_model);
if(options.get_bool_option("paths"))
{
verifier =
util_make_unique<all_properties_verifier_with_trace_storaget<
java_single_path_symex_checkert>>(
options, ui_message_handler, goto_model);
}
else
{
verifier =
util_make_unique<all_properties_verifier_with_trace_storaget<
java_multi_path_symex_checkert>>(
options, ui_message_handler, goto_model);
}
}
}

Expand Down
56 changes: 44 additions & 12 deletions src/cbmc/cbmc_parse_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ Author: Daniel Kroening, [email protected]
#include <goto-checker/multi_path_symex_checker.h>
#include <goto-checker/multi_path_symex_only_checker.h>
#include <goto-checker/properties.h>
#include <goto-checker/single_path_symex_checker.h>
#include <goto-checker/single_path_symex_only_checker.h>
#include <goto-checker/stop_on_fail_verifier.h>

#include <goto-programs/adjust_float_expressions.h>
Expand Down Expand Up @@ -559,25 +561,39 @@ int cbmc_parse_optionst::doit()
options.get_bool_option("program-only") ||
options.get_bool_option("show-vcc"))
{
if(!options.get_bool_option("paths"))
if(options.get_bool_option("paths"))
{
all_properties_verifiert<single_path_symex_only_checkert> verifier(
options, ui_message_handler, goto_model);
(void)verifier();
}
else
{
all_properties_verifiert<multi_path_symex_only_checkert> verifier(
options, ui_message_handler, goto_model);
(void)verifier();
return CPROVER_EXIT_SUCCESS;
}

return CPROVER_EXIT_SUCCESS;
}

if(
options.get_bool_option("dimacs") || !options.get_option("outfile").empty())
{
if(!options.get_bool_option("paths"))
if(options.get_bool_option("paths"))
{
stop_on_fail_verifiert<single_path_symex_checkert> verifier(
options, ui_message_handler, goto_model);
(void)verifier();
}
else
{
stop_on_fail_verifiert<multi_path_symex_checkert> verifier(
options, ui_message_handler, goto_model);
(void)verifier();
return CPROVER_EXIT_SUCCESS;
}

return CPROVER_EXIT_SUCCESS;
}

if(options.is_set("cover"))
Expand All @@ -596,20 +612,36 @@ int cbmc_parse_optionst::doit()
std::unique_ptr<goto_verifiert> verifier = nullptr;

if(
!options.get_bool_option("paths") && !options.is_set("cover") &&
!options.get_bool_option("dimacs") && options.get_option("outfile").empty())
!options.is_set("cover") && !options.get_bool_option("dimacs") &&
options.get_option("outfile").empty())
{
if(options.get_bool_option("stop-on-fail"))
{
verifier =
util_make_unique<stop_on_fail_verifiert<multi_path_symex_checkert>>(
options, ui_message_handler, goto_model);
if(options.get_bool_option("paths"))
{
verifier =
util_make_unique<stop_on_fail_verifiert<single_path_symex_checkert>>(
options, ui_message_handler, goto_model);
}
else
{
verifier =
util_make_unique<stop_on_fail_verifiert<multi_path_symex_checkert>>(
options, ui_message_handler, goto_model);
}
}
else
{
verifier = util_make_unique<
all_properties_verifier_with_trace_storaget<multi_path_symex_checkert>>(
options, ui_message_handler, goto_model);
if(options.get_bool_option("paths"))
{
verifier = util_make_unique<all_properties_verifier_with_trace_storaget<
single_path_symex_checkert>>(options, ui_message_handler, goto_model);
}
else
{
verifier = util_make_unique<all_properties_verifier_with_trace_storaget<
multi_path_symex_checkert>>(options, ui_message_handler, goto_model);
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/goto-checker/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ SRC = bmc_util.cpp \
counterexample_beautification.cpp \
cover_goals_report_util.cpp \
incremental_goto_checker.cpp \
goto_symex_property_decider.cpp \
goto_trace_storage.cpp \
goto_verifier.cpp \
multi_path_symex_checker.cpp \
multi_path_symex_only_checker.cpp \
properties.cpp \
report_util.cpp \
single_path_symex_checker.cpp \
single_path_symex_only_checker.cpp \
solver_factory.cpp \
symex_coverage.cpp \
symex_bmc.cpp \
Expand Down
101 changes: 101 additions & 0 deletions src/goto-checker/bmc_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,3 +269,104 @@ void update_status_of_not_checked_properties(
}
}
}

void update_status_of_unknown_properties(
propertiest &properties,
std::unordered_set<irep_idt> &updated_properties)
{
for(auto &property_pair : properties)
{
if(property_pair.second.status == property_statust::UNKNOWN)
{
// This could have any status except NOT_CHECKED.
// We consider them PASS because we do verification modulo bounds.
property_pair.second.status = property_statust::PASS;
updated_properties.insert(property_pair.first);
}
}
}

void output_coverage_report(
const std::string &cov_out,
const abstract_goto_modelt &goto_model,
const symex_bmct &symex,
ui_message_handlert &ui_message_handler)
{
if(
!cov_out.empty() &&
symex.output_coverage_report(goto_model.get_goto_functions(), cov_out))
{
messaget log(ui_message_handler);
log.error() << "Failed to write symex coverage report to '" << cov_out
<< "'" << messaget::eom;
}
}

static void postprocess_equation(
symex_bmct &symex,
symex_target_equationt &equation,
const optionst &options,
const namespacet &ns,
ui_message_handlert &ui_message_handler)
{
// add a partial ordering, if required
if(equation.has_threads())
{
std::unique_ptr<memory_model_baset> memory_model =
get_memory_model(options, ns);
memory_model->set_message_handler(ui_message_handler);
(*memory_model)(equation);
}

messaget log(ui_message_handler);
log.statistics() << "size of program expression: "
<< equation.SSA_steps.size() << " steps" << messaget::eom;

slice(symex, equation, ns, options, ui_message_handler);

if(options.get_bool_option("validate-ssa-equation"))
{
symex.validate(validation_modet::INVARIANT);
}
}

void perform_symex(
abstract_goto_modelt &goto_model,
symex_bmct &symex,
symbol_tablet &symex_symbol_table,
symex_target_equationt &equation,
const optionst &options,
const namespacet &ns,
ui_message_handlert &ui_message_handler)
{
auto get_goto_function =
[&goto_model](
const irep_idt &id) -> const goto_functionst::goto_functiont & {
return goto_model.get_goto_function(id);
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we maybe tweak the goto_symext interface a bit? Looking at get_function_from_goto_functions (symex_main.cpp) we now define this helper function multiple times.


symex.symex_from_entry_point_of(get_goto_function, symex_symbol_table);

postprocess_equation(symex, equation, options, ns, ui_message_handler);
}

void perform_symex(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused. It seems two commits now introduce the same. They actually do, the lines above already contain the same code.

Copy link
Member Author

@peterschrammel peterschrammel Feb 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's exactly the problem. The goto-symex interface is broken in this respect. We should have a function that returns a path_storaget::patht for the initial state at the entry point; and then we can resume from that... and everything becomes nice and uniform.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That should be fixable?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but I'll go ahead with the current version for now and clean up the goto-symex interface later this week. #4071

abstract_goto_modelt &goto_model,
symex_bmct &symex,
path_storaget::patht &resume,
symbol_tablet &symex_symbol_table,
const optionst &options,
const namespacet &ns,
ui_message_handlert &ui_message_handler)
{
auto get_goto_function =
[&goto_model](
const irep_idt &id) -> const goto_functionst::goto_functiont & {
return goto_model.get_goto_function(id);
};

symex.resume_symex_from_saved_state(
get_goto_function, resume.state, &resume.equation, symex_symbol_table);

postprocess_equation(symex, resume.equation, options, ns, ui_message_handler);
}
Loading