-
Notifications
You must be signed in to change notification settings - Fork 273
Cleanup error handling of cbmc/ folder #2703
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
Cleanup error handling of cbmc/ folder #2703
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approve subject to addressing the comments.
src/cbmc/symex_coverage.cpp
Outdated
|
||
// identify the file name, inlined functions aren't properly | ||
// accounted for | ||
goto_programt::const_targett end_function= | ||
--gf_it->second.body.instructions.end(); | ||
assert(end_function->is_end_function()); | ||
INVARIANT(end_function->is_end_function(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DATA_INVARIANT I think.
src/cbmc/symex_coverage.cpp
Outdated
file_name=end_function->source_location.get_file(); | ||
assert(!file_name.empty()); | ||
INVARIANT(!file_name.empty(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DATA_INVARIANT
src/util/parse_options.cpp
Outdated
catch(invalid_user_input_exceptiont &e) | ||
{ | ||
std::cerr << e.what() << "\n"; | ||
return CPROVER_EXIT_EXCEPTION; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CPROVER_EXIT_USAGE_ERROR ?
src/cbmc/bmc_cover.cpp
Outdated
@@ -241,7 +241,8 @@ bool bmc_covert::operator()() | |||
cover_goals.add(l); | |||
} | |||
|
|||
assert(cover_goals.size()==goal_map.size()); | |||
INVARIANT(cover_goals.size()==goal_map.size(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
apply clang-format
src/cbmc/cbmc_main.cpp
Outdated
|
||
int res=parse_options.main(); | ||
int res = parse_options.main(); | ||
|
||
#ifdef IREP_HASH_STATS | ||
std::cout << "IREP_HASH_CNT=" << irep_hash_cnt << '\n'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indentation
src/util/exception_utils.h
Outdated
std::string what() const noexcept | ||
{ | ||
std::string res; | ||
res += "\nInvalid User Input Exception\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd remove the word Exception
.
src/cbmc/cbmc_solvers.cpp
Outdated
error() << "sorry, this solver does not support beautification" << eom; | ||
throw 0; | ||
throw invalid_user_input_exceptiont( | ||
"Sorry, this solver does not support beautification", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe this solver
-> the chosen solver
? (same below)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And drop "sorry" - we don't apologise elsewhere either.
src/util/parse_options.cpp
Outdated
} | ||
catch(invalid_user_input_exceptiont &e) | ||
{ | ||
std::cerr << e.what() << "\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. This must go into a message stream.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was like this in the original design, but then I saw during rebasing on develop, that recently a similar change was eliminated, so I thought that it must have been that this is more appropriate. If I am also to do that now, I will need to add a messaget
into parse_options_baset
, which will require changes in various places
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found exactly what I was referring to. So parse_options_baset
doesn't seem to inherit from messaget
and doesn't contain a reference to a messaget
. If I do this, then I get loads of compilation errors regarding ambiguous calls to things like status()
, get_message_handler()
, etc.
It's also consistent with the rest of the file. parse_options_baset::usage_error()
, parse_options_baset::unknown_options_msg()
seem to be following the same pattern of using std::cerr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the risk of contradicting @peterschrammel: I don't think a message stream can be used here, because setting up the desired one requires successful parsing of command-line options (picking, e.g., JSON output with a verbosity of 5). Hence I'm with @NlightNFotis that using std::cerr
is correct here.
src/cbmc/cbmc_main.cpp
Outdated
@@ -41,11 +41,9 @@ int wmain(int argc, const wchar_t **argv_wide) | |||
int main(int argc, const char **argv) | |||
{ | |||
#endif | |||
try |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please squash this with the first commit that introduce the change that you undo here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a good direction of work to me, but I'd suggest to make this as clean as possible unless there is a need to rush it in? If so, please break it apart into separate pull requests as the need for further discussion varies widely among the commits.
src/cbmc/bmc_cover.cpp
Outdated
@@ -241,7 +241,8 @@ bool bmc_covert::operator()() | |||
cover_goals.add(l); | |||
} | |||
|
|||
assert(cover_goals.size()==goal_map.size()); | |||
INVARIANT(cover_goals.size()==goal_map.size(), | |||
"We add coverage for each goal"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The coding standard says that error messages start with a lower-case letter.
src/cbmc/symex_coverage.cpp
Outdated
assert(cov.second.num_executions>0); | ||
INVARIANT(cov.second.num_executions>0, | ||
// FIXME I don't know what this means | ||
"Number of executions most be positive"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be a PRECONDITION
. A coverage entry can only exist when a location has actually been covered in at least one execution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a problem with that, in that the PRECONDITION
according to documentation should only contain unmodified arguments to a function, but I can change it, since it makes it easier to drop the message which appears incorrect as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You might use a DATA_INVARIANT
, paraphrasing in the message what I said above (coverage entries can only exist with at least one execution).
src/cbmc/cbmc_main.cpp
Outdated
catch(invalid_user_input_exceptiont &e) | ||
{ | ||
std::cerr << e.what() << std::endl; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Design note: I don't think such an exception should propagate out of parse_options
for the key task of parse_options
is to parse options? If anything goes wrong it should and does return an error code. Having both error codes and exceptions seems wrong to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a comment on outdated code. The error handling is now being contained in parse_optionst::main()
, and doesn't escape that context. parse_optionst::main()
will indeed return an error code, that is is being handled in cbmc_main
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, it also appears that parse_optionst
was mainly useful during the evolution of the code, but now that has been rebased, its usefulness has diminished, so I am trying to eliminate it.
src/util/exception_utils.h
Outdated
{ | ||
} | ||
|
||
std::string what() const noexcept |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this should be a header-only class. Add a cpp file and move the implementation of at least this function over there. No need to inline it everywhere, will just unnecessarily increase the size of the binary.
src/cbmc/cbmc_solvers.cpp
Outdated
@@ -235,20 +239,38 @@ std::unique_ptr<cbmc_solverst::solvert> cbmc_solverst::get_smt2( | |||
|
|||
void cbmc_solverst::no_beautification() | |||
{ | |||
if(options.get_bool_option("beautify")) | |||
bool beautify = options.get_bool_option("beautify"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this temporary introduced?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I remember I had a reason in the beginning but I may have refactored it enough that it's now unneeded.
src/cbmc/cbmc_solvers.cpp
Outdated
error() << "sorry, this solver does not support beautification" << eom; | ||
throw 0; | ||
throw invalid_user_input_exceptiont( | ||
"Sorry, this solver does not support beautification", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And drop "sorry" - we don't apologise elsewhere either.
src/cbmc/cbmc_solvers.cpp
Outdated
if(options.get_bool_option("all-properties") || | ||
options.get_option("cover")!="" || | ||
options.get_option("incremental-check")!="") | ||
bool all_properties = options.get_bool_option("all-properties"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const
(here and below)
src/cbmc/cbmc_solvers.cpp
Outdated
options.get_option("cover")!="" || | ||
options.get_option("incremental-check")!="") | ||
bool all_properties = options.get_bool_option("all-properties"); | ||
bool cover = options.get_option("cover") != ""; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While you're cleaning this up: use .is_set
instead of get_option(...) != ""
src/util/parse_options.h
Outdated
@@ -35,6 +35,17 @@ class parse_options_baset | |||
bool parse_result; | |||
}; | |||
|
|||
class parse_optionst : public parse_options_baset |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure we need this derived class: can't it just be changed in parse_options_baset
and make everyone benefit without changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not needed anymore. I have eliminated it.
src/util/exception_utils.h
Outdated
res += "Option: " + option + "\n"; | ||
res += "Reason: " + reason; | ||
// Print an optional correct usage message assuming correct input parameters have been passed | ||
res += correct_input.empty() ? "\n" : " Try: " + correct_input + "\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "Try: ..."
portion should better be on a new line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tautschnig Suggested to drop the Try
altogether, and just add in the various constructor callsites so that it reads more like a sentence.
3c9225c
to
f06cbea
Compare
@peterschrammel You have a red (blocker) cross applied to this. All your points have now been addressed. Can you take a look now and tell me if there's anything more you would want explained or changed? |
@tautschnig Hi, can you also take a look to see if it's closer to what you expect? It's the same as before, but cleaned up and the changes suggested applied. The only extra is the last commit, which I thought makes sense to not be squashed, as it is a good atomic change (it replaces |
src/cbmc/cbmc_main.cpp
Outdated
@@ -41,9 +41,11 @@ int wmain(int argc, const wchar_t **argv_wide) | |||
int main(int argc, const char **argv) | |||
{ | |||
#endif | |||
cbmc_parse_optionst parse_options(argc, argv); | |||
try | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is undone two commits later. Why is this change made at all?
|
||
#include "exception_utils.h" | ||
|
||
std::string invalid_user_input_exceptiont::what() const noexcept |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally, there should also be a version hat can serialise into json and XML in a more structure way (in a future PR).
src/cbmc/bv_cbmc.cpp
Outdated
} | ||
DATA_INVARIANT( | ||
expr.operands().size() != 4, | ||
"waitfor expression is expected to have four operands"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chrisr-diffblue, @martin-cs, the source location is lost here. Would it be possible to have variants of the INVARIANT macros that take a source location explicitly so that it can be output in a structured way?
@NlightNFotis, the changes in f257667 that are later undone in 017c1b0 need to be removed. |
Could this one please be rebased and cleaned up with regard to the comments raised by @peterschrammel - then it might be good to go. |
@tautschnig Yes, this is waiting for us to decide on a clean way to create a more structured, "variadic" invariant, that can take a |
Apart from the fact that the specific bit of code that @peterschrammel commented on is now gone from the repository: can't we just solve this by doing |
f06cbea
to
3bd4322
Compare
@tautschnig I have now rebased the PR and I'm waiting for CI to pass. Then it should be good to go. We decided to go ahead with this now and we can implement the structured invariants later. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are still changes in the individual commits that just modify what was added in one of the other commits in this series. Some soft reset and the use of git add -p
seems to be due.
src/cbmc/cbmc_solvers.h
Outdated
@@ -68,13 +68,13 @@ class cbmc_solverst:public messaget | |||
|
|||
prop_convt &prop_conv() const | |||
{ | |||
assert(prop_conv_ptr!=nullptr); | |||
PRECONDITION(prop_conv_ptr!=nullptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit pick: clang-format.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR failed Diffblue compatibility checks (cbmc commit: 3bd4322).
Status will be re-evaluated on next push.
Please contact @peterschrammel, @thk123, or @allredj for support.
Common spurious failures:
- the cbmc commit has disappeared in the mean time (e.g. in a force-push)
- the author is not in the list of contributors (e.g. first-time contributors).
3bd4322
to
2e6d6a0
Compare
@tautschnig I have implemented all of the changes suggested in your comments, and Peter's comments (bar the structured invariant). I have also pinged Peter for a re-review. Can you take a look at it and green-light it if you think it's good to go? |
src/cbmc/cbmc_solvers.h
Outdated
return *prop_conv_ptr; | ||
} | ||
|
||
propt &prop() const | ||
{ | ||
PRECONDITION(prop_ptr!=nullptr); | ||
PRECONDITION(prop_ptr != nullptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still in the wrong commit, fixing up a change from an earlier commit.
@@ -43,7 +43,7 @@ int main(int argc, const char **argv) | |||
#endif | |||
cbmc_parse_optionst parse_options(argc, argv); | |||
|
|||
int res=parse_options.main(); | |||
int res = parse_options.main(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary change?
std::string res; | ||
res += "\nInvalid User Input\n"; | ||
res += "Option: " + option + "\n"; | ||
res += "Reason: " + reason; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wishlist: please add a test for this, i.e., intentionally use CBMC with incorrect options.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need this as part of this PR, or can it go in as part of a follow up PR for example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Up to you, as long as it happens at some point :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We plan to make some further improvements to user error handling, so we'll definitely be adding suitable test cases as part of that work, so I'd be happy for this PR to go in, with tests following as part of the later improvements.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR failed Diffblue compatibility checks (cbmc commit: 2e6d6a0).
Status will be re-evaluated on next push.
Please contact @peterschrammel, @thk123, or @allredj for support.
Common spurious failures:
- the cbmc commit has disappeared in the mean time (e.g. in a force-push)
- the author is not in the list of contributors (e.g. first-time contributors).
Perform various cleanups of the error handling mechanisms in the
src/cbmc/
folder. These include turningassert
s intoINVARIANT
s andPRECONDITION
s as well as a new custom exception class.