Skip to content

Commit 8958d37

Browse files
WIP Add some information about new option to the manual
1 parent 6a0522e commit 8958d37

File tree

1 file changed

+156
-0
lines changed

1 file changed

+156
-0
lines changed

doc/cbmc-user-manual.md

+156
Original file line numberDiff line numberDiff line change
@@ -2014,6 +2014,162 @@ Flag | Check
20142014
`--uninitialized-check` | add checks for uninitialized locals (experimental)
20152015
`--error-label label` | check that given label is unreachable
20162016

2017+
#### Generating/Replacing function bodies
2018+
2019+
Sometimes implementations for called functions are not available in the goto
2020+
program, or it is desirable to replace bodies of functions with certain
2021+
predetermined stubs (for example to confirm that these functions are never
2022+
called, or to indicate that these functions will never return). For this purpose
2023+
goto-instrument provides the `--generate-function-body` and
2024+
`--replace-function-body` options, that take a regular expression (in
2025+
[ECMAScript syntax](http://en.cppreference.com/w/cpp/regex/ecmascript)) that
2026+
describes the names of the functions to generate or replace, the difference
2027+
being that `--generate-function-body` will only generate bodies of functions
2028+
that do not already have one, whereas `--replace-function-body` will do this and
2029+
in addition also replace existing bodies of functions with the stub.
2030+
2031+
The shape of the stub itself can be chosen with the `--replace-function-body-options`
2032+
parameter, which can take the following values:
2033+
2034+
Option | Result
2035+
-----------------------------|-------------------------------------------------------------
2036+
`nondet-return` | Do nothing and return a nondet result (this is the default)
2037+
`empty` | Delete the body of the function
2038+
`assert-false` | Make the body contain an assert(false)
2039+
`assume-false` | Make the body contain an assume(false)
2040+
`assert-false-assume-false` | Combines assert-false and assume-false
2041+
`havoc` | Set the contents of parameters and globals to nondet
2042+
2043+
The various combinations of assert-false and assume-false can be used to
2044+
indicate that functions shouldn't be called, that they will never return or
2045+
both.
2046+
2047+
Example: We have a program like this:
2048+
2049+
// error_example.c
2050+
#include <stdlib.h>
2051+
2052+
void api_error(void);
2053+
void internal_error(void);
2054+
2055+
int main(void)
2056+
{
2057+
int arr[10] = {1,2,3,4,5, 6, 7, 8, 9, 10};
2058+
int sum = 0;
2059+
for(int i = 1; i < 10; ++i)
2060+
{
2061+
sum += arr[i];
2062+
}
2063+
if(sum != 55)
2064+
{
2065+
// we made a mistake when calculating the sum
2066+
internal_error();
2067+
}
2068+
if(rand() < 0)
2069+
{
2070+
// we think this cannot happen
2071+
api_error();
2072+
}
2073+
return 0;
2074+
}
2075+
2076+
Now, we can compile the program and detect that the error functions are indeed
2077+
called by invoking these commands
2078+
2079+
goto-cc error_example.c -o error_example.goto
2080+
# Replace all functions ending with _error
2081+
# (Excluding those starting with __)
2082+
# With ones that have an assert(false) body
2083+
goto-instrument error_example.goto error_example_replaced.goto \
2084+
--replace-function-body '(?!__).*_error' \
2085+
--replace-function-body-options assert-false
2086+
cbmc error_example_replaced.goto
2087+
2088+
Which gets us the output
2089+
2090+
> ** Results:
2091+
> [internal_error.assertion.1] assertion false: FAILURE
2092+
> [api_error.assertion.1] assertion false: FAILURE
2093+
>
2094+
>
2095+
> ** 2 of 2 failed (2 iterations)
2096+
> VERIFICATION FAILED
2097+
2098+
As opposed to the verification success we would have gotten without the
2099+
replacement
2100+
2101+
2102+
The havoc option takes further parameters `globals` and `params` with this
2103+
syntax: `havoc[,globals:<regex>][,params:<regex>]` (where the square brackets
2104+
indicate an optional part). The regular expressions have the same format as the
2105+
those for the `--replace-function-body` and `--generate-function-body` options
2106+
and indicate which globals and function parameters should be set to nondet. All
2107+
regular expressions require exact matches (i.e. the regular expression `ab?`
2108+
will match 'a' and 'b' but not 'adrian' or 'bertha').
2109+
2110+
Example: With a C program like this
2111+
2112+
struct Complex {
2113+
double real;
2114+
double imag;
2115+
};
2116+
2117+
struct Complex AGlobalComplex;
2118+
int do_something_with_complex(struct Complex *complex);
2119+
2120+
And the command line
2121+
2122+
goto-instrument in.goto out.goto
2123+
--replace-function-body do_something_with_complex
2124+
--replace-function-body-options
2125+
'havoc,params:.*,globals:AGlobalComplex'
2126+
2127+
The goto code equivalent of the following will be generated:
2128+
2129+
int do_something_with_complex(struct Complex *complex)
2130+
{
2131+
if(complex)
2132+
{
2133+
complex->real = nondet_double();
2134+
complex->imag = nondet_double();
2135+
}
2136+
return nondet_int();
2137+
}
2138+
2139+
A note on limitations: Because only static information is used for code
2140+
generation, arrays of unknown size and pointers will not be affected by this;
2141+
Which means that for code like this:
2142+
2143+
struct Node {
2144+
int val;
2145+
struct Node *next;
2146+
};
2147+
2148+
void do_something_with_node(struct Node *node);
2149+
2150+
Code like this will be generated:
2151+
2152+
void do_something_with_node(struct Node *node)
2153+
{
2154+
if(node)
2155+
{
2156+
node->val = nondet_int();
2157+
node->next = nondet_0();
2158+
}
2159+
}
2160+
2161+
Note that no attempt to follow the `next` pointer is made. If an array of
2162+
unknown (or 0) size is encountered, a diagnostic is emitted and the array
2163+
is not further examined.
2164+
2165+
Some care must be taken when choosing the regular expressions for globals and
2166+
functions. Names starting with `__` are reserved for internal purposes; For
2167+
example, replacing functions or setting global variables with the `__CPROVER`
2168+
prefix might make analysis impossible. To avoid doing this by accident, negative
2169+
lookahead can be used. For example, `(?!__).*` matches all names not starting
2170+
with `__`.
2171+
2172+
20172173
\subsection man_instrumentation-api The CPROVER API Reference
20182174

20192175
The following sections summarize the functions available to programs

0 commit comments

Comments
 (0)