-
Notifications
You must be signed in to change notification settings - Fork 277
Complexity graph #7081
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
Draft
bquiring
wants to merge
36
commits into
diffblue:develop
Choose a base branch
from
bquiring:complexity-graph
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Complexity graph #7081
Changes from all commits
Commits
Show all changes
36 commits
Select commit
Hold shift + click to select a range
aef4738
initial cfg dot program
bquiring 831ccf5
disable default
bquiring 6070b36
exclude unreachable functions from the control flow graph
bquiring 6f7aea6
revise graph styling, add new metrics
bquiring 78ee6fc
add metrics, use forall loops
bquiring a220835
refactor, add symex instrumentation and add this to default cbmc call…
bquiring e028920
add solver instrumentation
bquiring 78c66fc
instrument solver to fail, and constant propagator to be dumber. Disa…
bquiring e214941
add option to track symex coverage without generating a report
bquiring dafcdcb
moved around files. updated but broken
bquiring 2a81ed8
working
bquiring 30a73b2
add dumping of function instructions
bquiring 0b528e5
better displaying of instructions
bquiring c6b8d15
display instruction-level complexity
bquiring 8eaff6a
disable conver_assignments debugging
bquiring 9cd0f0e
fix html bug with dollar signs and colons and add instruction dumping…
bquiring 6b03cbb
updates
bquiring e5f15ee
rebase
bquiring 3104abf
add short README
bquiring b92fb2b
small change
bquiring 0cf70f7
fix build break
bquiring ea706fd
rebase
bquiring 18b269a
updates to metrics and display
bquiring ab365ff
update library function list
bquiring d9e6f43
update library function styling
bquiring d06a8f5
add document and refactor
bquiring 945486e
more refactor and documentation
bquiring 51933bf
revert changes to remove_function_pointers
bquiring 8ae5f37
patch CBMC bug for loop computation
bquiring ac97769
updates to documentation
bquiring a3b027e
address Jim's comments
bquiring 0ff6966
revert files
bquiring 3eedead
revert files
bquiring e03d478
update command line flags
bquiring fdadc05
move README
bquiring f99b996
small
bquiring File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
[CPROVER Manual TOC](../) | ||
|
||
## Complexity Graph | ||
|
||
This tool is meant to help decompose CBMC proofs. | ||
It does this by producing a control-flow graph that contains information about where CBMC may run into issues. | ||
|
||
``` | ||
goto-instrument FILE.goto FLAGS | ||
``` | ||
|
||
The recommended file to use is `FUNCTION_harness1.goto` which is produced from the Makefile provided in the starter kit. If this is not available, use `goto-cc` to compile all relevant source files into a `.goto` file. | ||
We recommend this file because it is produced before any program transformations are made, which can complicate the graph. | ||
|
||
## Relevant FLAGS | ||
|
||
--show-complexity-graph FILE.dot | ||
instructs CBMC to write the graph to the .dot file | ||
This can be compiled to a PDF by using the command | ||
``` | ||
dot -Tpdf FILE.dot -o FILE.pdf | ||
``` | ||
|
||
|
||
--complexity-graph-roots FUNCTION-NAME | ||
Instructs CBMC to generate the graph spanned by this function. This flag can be passed multiple times and produces one graph spanned by all roots. If no roots are provided, all functions in the provided source files will be used. | ||
Typically this will be `FUNCTION_harness`. | ||
|
||
|
||
--remove-function-body FUNCTION-NAME | ||
Removes the body of a function, which has the effect of removing all outedges of that vertex from the graph. | ||
|
||
|
||
--omit-function FUNCTION-NAME | ||
Omits a function from the graph entirely. Useful for removing high-indegree sink nodes to reduce visual clutter. | ||
|
||
|
||
--constant-propagator | ||
Recommended to run for the reason that it simplifies the underlying program, and hence the graph. | ||
|
||
|
||
--omit-function-pointers | ||
Removes function pointer edges from the graph, which have a habit of producing visual clutter. | ||
|
||
|
||
--add-library | ||
Includes the CBMC library for functions like `malloc`, `free`, etc. | ||
|
||
--complexity-graph-global-scores | ||
Uses a more global notion of scoring, where the "global score" for a node is the number of paths to that node multiplied by the sum of the global scores of its children. | ||
|
||
The following flags can be used with the main CBMC executable | ||
``` | ||
cbmc FILE.goto FLAGS | ||
``` | ||
|
||
--show-complexity-graph-with-symex FILE.dot | ||
Write the complexity graph with symbolic execution information to FILE.dot. | ||
|
||
|
||
--show-complexity-graph-with-solver FILE.dot | ||
Write the complexity graph with symbolic execution and solver formula information to FILE.dot. | ||
This flag requires the addition of `--write-solver-stats-to FILE.out` to obtain solver formula information. | ||
|
||
|
||
--complexity-graph-instructions | ||
When used with '--show-complexity-graph-with-symex' or '--show-complexity-graph-with-solver' displays the instructions of the program that have a high cost in symbolic execution and/or the solver formula. | ||
|
||
## Reading the graph | ||
|
||
### Node shapes | ||
|
||
- Rectangluar nodes: normal functions | ||
- Elliptical nodes: private functions | ||
- Diamond nodes: functions with no body | ||
- Arrow-shaped nodes: function pointers | ||
- Pentagon: standard/CBMC library functions | ||
|
||
### Node colors | ||
|
||
The intensity of red coloring on a node is a display of its complexity relative to other nodes in the graph. | ||
|
||
When using `--show-complexity-graph-with-symex` with `--complexity-graph-instructions`, intensity of pink on instructions shows the complexity of that instruction in symbolic execution, and intensity of yellow shows the complexity of that instruction in the creation of the solver formula. | ||
|
||
|
||
## Sample interaction | ||
|
||
Suppose we have a function `foobar` and we'd like to do a proof for it. | ||
After creating a GOTO file `foobar_harness1.goto` with the starter kit or `goto-cc`, try the following | ||
|
||
``` | ||
goto-instrument foobar_harness1.goto --show-complexity-graph graph.dot --complexity-graph-roots foobar | ||
``` | ||
Followed by | ||
``` | ||
dot -Tpdf graph.dot -o graph.pdf | ||
``` | ||
|
||
This will display the call graph for foobar. | ||
The first step is to take steps to clean the graph. | ||
|
||
Likely, you can ignore function pointers at this point. See [this page](http://cprover.diffblue.com/md__home_travis_build_diffblue_cbmc_doc_architectural_restrict-function-pointer.html) for how to restrict function pointers - the information provided in the graph displays CBMC's sound overapproximation of what functions can be targets of which function pointers. | ||
|
||
Additionally, there may be some high-indegree functions in the graph that don't appear to be useful and just complicate the graph. | ||
Let's say one of those functions is `notuseful`. | ||
We can then run a new command | ||
``` | ||
goto-instrument foobar_harness1.goto --show-complexity-graph graph.dot --complexity-graph-roots foobar --complexity-graph-omit-function-pointers --complexity-graph-omit-function notuseful | ||
``` | ||
Which should provide a cleaner graph to inspect. | ||
|
||
|
||
When doing a proof, you should use information provided in the graph along with some domain knowledge about the codebase to decide where to decompose. See `doc/cprover-manual/contracts-functions.md` for a tutorial on proof decomposition using function contracts, which we refer to as abstracting a function. | ||
It's good to abstract functions that are complex. In the case that there is a simple function `g` that calls a complex function `f`, it may be better to abstract `g` if the contract is easier to write. | ||
A good way to approximate where a contract is easy to write is by how many memory locations a function can write to. | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,6 +58,7 @@ Author: Daniel Kroening, [email protected] | |
#include <goto-programs/remove_skip.h> | ||
#include <goto-programs/remove_unused_functions.h> | ||
#include <goto-programs/set_properties.h> | ||
#include <goto-programs/show_complexity_graph.h> | ||
#include <goto-programs/show_goto_functions.h> | ||
#include <goto-programs/show_properties.h> | ||
#include <goto-programs/show_symbol_table.h> | ||
|
@@ -334,8 +335,10 @@ void cbmc_parse_optionst::get_command_line_options(optionst &options) | |
options.set_option("trace", true); | ||
} | ||
|
||
options.set_option("symex-record-coverage", cmdline.get_values ("symex-record-coverage")); | ||
if(cmdline.isset("symex-coverage-report")) | ||
{ | ||
options.set_option("symex-record-coverage", true); | ||
options.set_option( | ||
"symex-coverage-report", | ||
cmdline.get_value("symex-coverage-report")); | ||
|
@@ -372,6 +375,51 @@ void cbmc_parse_optionst::get_command_line_options(optionst &options) | |
parse_solver_options(cmdline, options); | ||
} | ||
|
||
void set_complexity_graph_options (const cmdlinet &cmdline, optionst &options) { | ||
if (cmdline.isset ("show-complexity-graph-with-symex") | ||
|| cmdline.isset ("show-complexity-graph-with-solver")) { | ||
options.set_option("symex-record-coverage", true); | ||
} | ||
|
||
options.set_option ("show-complexity-graph", cmdline.get_values ("show-complexity-graph")); | ||
options.set_option ("show-complexity-graph-with-symex", cmdline.get_values ("show-complexity-graph-with-symex")); | ||
options.set_option ("show-complexity-graph-with-solver", cmdline.get_values ("show-complexity-graph-with-solver")); | ||
if (cmdline.isset ("complexity-graph-root")) | ||
{ | ||
std::stringstream stream; | ||
for (const std::string &val : cmdline.get_values("complexity-graph-root")) | ||
{ | ||
stream << val << ","; | ||
} | ||
options.set_option ("complexity-graph-roots", stream.str()); | ||
} | ||
|
||
if (cmdline.isset ("complexity-graph-omit-function")) | ||
{ | ||
std::stringstream stream; | ||
for (const std::string &val : cmdline.get_values("complexity-graph-omit-function")) | ||
{ | ||
stream << val << ","; | ||
} | ||
options.set_option ("complexity-graph-omit-function", stream.str()); | ||
} | ||
|
||
if (cmdline.isset ("complexity-graph-global-scores")) | ||
{ | ||
options.set_option ("complexity-graph-global-scores", true); | ||
} | ||
|
||
if (cmdline.isset ("complexity-graph-omit-function-pointers")) | ||
{ | ||
options.set_option ("complexity-graph-omit-function-pointers", true); | ||
} | ||
|
||
if (cmdline.isset ("complexity-graph-instructions")) | ||
{ | ||
options.set_option ("complexity-graph-instructions", true); | ||
} | ||
} | ||
|
||
/// invoke main modules | ||
int cbmc_parse_optionst::doit() | ||
{ | ||
|
@@ -499,6 +547,8 @@ int cbmc_parse_optionst::doit() | |
return CPROVER_EXIT_SUCCESS; | ||
} | ||
|
||
set_complexity_graph_options (cmdline, options); | ||
|
||
int get_goto_program_ret = | ||
get_goto_program(goto_model, options, cmdline, ui_message_handler); | ||
|
||
|
@@ -635,6 +685,7 @@ int cbmc_parse_optionst::doit() | |
verifier = util_make_unique< | ||
all_properties_verifier_with_trace_storaget<multi_path_symex_checkert>>( | ||
options, ui_message_handler, goto_model); | ||
// TODO: this is the branch triggered by default | ||
} | ||
} | ||
else | ||
|
@@ -894,6 +945,8 @@ void cbmc_parse_optionst::help() | |
" --show-parse-tree show parse tree\n" | ||
" --show-symbol-table show loaded symbol table\n" | ||
HELP_SHOW_GOTO_FUNCTIONS | ||
HELP_SHOW_COMPLEXITY_GRAPH | ||
HELP_SHOW_COMPLEXITY_GRAPH_CBMC | ||
HELP_VALIDATE | ||
"\n" | ||
"Program instrumentation options:\n" | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back 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.
What needs to be done here? Maybe file an issue on whatever it is instead of leaving this isn the code.