-
Notifications
You must be signed in to change notification settings - Fork 262
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
Add goto-bmc
, a new tool to run only the verifier
#7762
Add goto-bmc
, a new tool to run only the verifier
#7762
Conversation
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## develop #7762 +/- ##
===========================================
+ Coverage 78.06% 78.59% +0.53%
===========================================
Files 1693 1696 +3
Lines 193308 193450 +142
===========================================
+ Hits 150899 152049 +1150
+ Misses 42409 41401 -1008
☔ View full report in Codecov by Sentry. |
3daedb9
to
e993c8f
Compare
d3cd4ee
to
b23116a
Compare
src/libcprover-cpp/api.h
Outdated
@@ -98,7 +98,8 @@ struct api_sessiont | |||
|
|||
/// Implement necessary transformations to reduce model to core-GOTO, before | |||
/// being fed to symex. | |||
/// @return The function return `true` if it failed because CBMC produced an error. | |||
/// @return The function return `true` if it failed because CBMC produced |
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.
return -> returns
// FOTIS' note: Modelled after `result_to_exit_code` in | ||
// `src/goto-checker/properties.cpp`. |
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 this be refactored to use the same code then?
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 can't do that because the functions use different types as inputs.
We have two types that are equivalent, but one of them is internal to CBMC (goto-checker
, really), and thus, we can't expose it to the C++ API (because of the internal headers issue), and the other is the C++ API equivalent, which is present in the headers for the API.
We have in the API (under verification_result.cpp
) a function which does the translation from result_internal -> result_external
, but we needed to have a function from result_external -> BMC_EXIT_CODE
. This is the function that was modelled under the equivalent one from result_internal -> BMC_EXIT_CODE
.
int argc, | ||
const char **argv) | ||
: parse_options_baset( | ||
CORE_CBMC_ONLY_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.
symex-ready
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.
These shouldn't be called symex-ready
- they refer to the tool not the goto-binaries.
But they will need to be made consistent to the actual tool name, which we settled on goto-bmc
(this is the name of the tool built). The references are artefacts from a previous change where we called the tool corebmc
but settled on goto-bmc
instead.
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.
Done.
CORE_CBMC_ONLY_OPTIONS, | ||
argc, | ||
argv, | ||
std::string("CORE_CBMC_ONLY") + CBMC_VERSION) |
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.
symex-ready
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.
Renamed to goto-bmc
- Done.
std::cout << api_message_get_string(message) << std::endl; | ||
} | ||
|
||
int core_cbmc_only_parse_optionst::doit() |
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.
symex-ready
class core_cbmc_only_parse_optionst : public parse_options_baset | ||
{ | ||
public: | ||
core_cbmc_only_parse_optionst(int argc, const char **argv); |
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.
symex-ready
virtual int doit(); | ||
}; | ||
|
||
#endif // CPROVER_CORE_BMC_PARSE_OPTIONS_H |
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.
symex-ready
/// Read a goto-binary from a given filename. | ||
/// @warning Will error out if it reads a source file. | ||
void read_goto_binary(std::string &file) const; |
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 should check that the goto binary is in symex-ready form. Of course the check is not implemented yet, but maybe this should be a comment or stub in the implementation?
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 track this functionality, by having a negative test under regression/goto-bmc/goto-bmc-non-symex-ready-goto
whose job is to fail when fed a non-symex-ready goto.
For now it fails with an invariant violation, so the error message leaves a lot to be desired, but when we fix the recognition of the symex-ready-goto binaries, this test is going to fail (because the invariant violation pattern is not going to be present in the output any more) and this will serve as our reminder to go back and fix that.
void read_goto_binary(std::string &file) const; | ||
|
||
/// True if file is goto-binary. | ||
bool is_goto_binary(std::string &file) const; |
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 here, -> is_symex_ready_goto_binary
?
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 don't want to do this, because we delegate to is_goto_binary
from src/goto-programs/read_goto_binary.cpp
which doesn't check the "level" of the goto-binary (whether transformations have been performed and which ones), so we can't really promise to give information we don't have.
src/libcprover-cpp/api.h
Outdated
private: | ||
std::unique_ptr<api_session_implementationt> implementation; | ||
|
||
/// Implement necessary transformations to reduce model to core-GOTO, before |
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.
symex-ready
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.
Done.
063e616
to
dfde351
Compare
src/libcprover-cpp/api.cpp
Outdated
return run_verifier(); | ||
} | ||
|
||
/// <FILL 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.
❓
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 was empty while we did some refactoring, acting as a reminder to fill in documentation once the code stabilised - it's filled in the next commit.
{ | ||
} | ||
|
||
void print_messages_to_stdout( |
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.
❓ What is this function for?
We should use log
for printing messages.
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 way the API works for now is it needs a callback to be passed to it, which it then calls to process messages from it.
This callback function needs to have a specific signature for it to be able to be registered with the API.
What we can do however, is change the references to std::cout
to output things via the log
instead.
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.
Done in 755f0f5
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.
Done in 755f0f5
Is that actually a good idea? With the new API the log exists inside the API layer but is not exposed. So by creating a log in the entry point doesn't that mean two instances of it exist at once?
src/goto-bmc/module_dependencies.txt
Outdated
@@ -0,0 +1,3 @@ | |||
util | |||
libcprover-cpp | |||
goto-programs |
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 this dependency? Shouldn't goto-bmc only depend on libcprover-cpp?
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 need this because of the check inside src/goto-bmc/goto_bmc_parse_options.cpp:52
which has a call to is_goto_binary
, defined under src/goto-programs/read_goto_binary.cpp
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.
If you need it then the API needs to expose it, no?
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 wrong, we already expose it in the API - we will change it to make it defer to the API (we already have this capability, probably lost the idea somewhere during refactoring)
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 log-handling function has to be fixed properly
ea812bd
to
5a1382a
Compare
@@ -79,11 +79,17 @@ struct api_sessiont | |||
/// Validate the loaded goto model | |||
void validate_goto_model() const; | |||
|
|||
// A simple API version information function. | |||
/// A simple API version information 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.
⛏️ Fix of existing documentation should be in a separate commit from the refactor, if the function is not changed as part of the refactor.
private: | ||
std::unique_ptr<api_session_implementationt> implementation; | ||
|
||
/// <FILL ME> | ||
bool preprocess_model() const; |
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.
💡 If this function is truly an implementation detail, then it would make sense to me for it to be a free function which is defined the .cpp
only.
⛏️ If the plan is to eventually use this as part of the publicly facing API then it isn't following the existing code pattern, which is to use the call-back to indicate errors and to return a void
result.
@@ -80,4 +80,8 @@ struct verification_resultt | |||
std::unique_ptr<verification_result_implt> _impl; | |||
}; | |||
|
|||
// Allow translation of `verifier_resultt` into a CPROVER_EXIT_CODES (so that |
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 use of a plural CPROVER_EXIT_CODES
suggests one result is turned into multiple codes.
🤔 Given that the API headers may be distributed without the rest of the project source, the reader maybe unaware of the existence of src/util/exit_codes.h
. So maybe we should just call this a Command Line Interface (CLI) return value/exit code; especially given that the result is not strongly typed.
@@ -1,7 +1,7 @@ | |||
CORE | |||
main.c | |||
|
|||
^EXIT=[127|134]$ |
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 commit title refers to moving tests, but this part is changing the test.
5a1382a
to
d98508a
Compare
To be able to run the BMC part of CBMC (symex and the decision-procedure) the API `verify_model` function has been split in two separate steps: the lowering step that applies all the transformations to the core-goto program and the verification step that only runs symex and the decision-procedure.
Add a new `goto-bmc` executable to CBMC that reads a core-goto program from a given binary file and runs symex and the decision procedure. This has been done by using the API functionalities instead of addin a new argument to CBMC.
d98508a
to
edea1bc
Compare
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.
Change requested has been fulfilled
In preparation for expanding the context beyond just the message stream.
This commit adds exiting on bad input files as is proper, instead of proceeding to further worse failures such as INVARIANT violations or even seg faults.
This would previously been left as a single unexpanded argument regardless of the number of arguments in the `.desc` file. For example `goto_bmc main.goto.symex_ready ''` in the case of no arguments specified. This should be expanded to match the number of arguments in the `options` variable. For example `goto_bmc main.goto.symex_ready` in the case of no arguments or `goto_bmc main.goto.symex_ready --argument1 --argument2` in the case of two arguments in the desc file.
Zero arguments should trigger an error as should files which fail the is_goto_binary check when a single file is specified.
Running `goto-bmc --help` was previously resulting in the tool exiting without displaying help text. This was due to the incomplete message being cached, but never sent to the console output before exiting.
The `parse_options_baset::main` function checks for a `--help` argument. It calls the `help()` member function and exits rather than calling `doit()` when this argument is specified. The duplicated code removed by this commit was misleading because it was never reached when the `--help` argument was specified.
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 missing error handling has now been added.
Setting the `CODEOWNERS` file entry for `src/goto-bmc` folder.
@@ -50,6 +50,7 @@ | |||
# These files change frequently and changes are medium-risk | |||
|
|||
/src/goto-analyzer/ @martin-cs @peterschrammel | |||
/src/goto-bmc/ @NlightNFotis @thomasspriggs @esteffin @TGWDB @peterschrammel |
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 adds a new tool,
goto-bmc
, which you can think of asCBMC
-lite: its purpose is to run only the backend, on a binary that is produced to besymex-ready
, i.e. have been lowered to a form that is accepted by symex without the need for any more transformations.The aim of the addition of this tool is to contribute towards the efforts to make
CBMC
and all of the assorted tools more modularised, by providing access to the backend of CBMC without needing to bundle frontends, transformation passes, etc, so that usage or integration of the tool into other software or (CI/dev) pipelines becomes easier.