-
Notifications
You must be signed in to change notification settings - Fork 273
Add JBMC user manual [DOC-9] #3404
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
Conversation
allredj
commented
Nov 13, 2018
- Each commit message has a non-empty body, explaining why the change was made.
- Methods or procedures I have added are documented, following the guidelines provided in CODING_STANDARD.md.
- Regression or unit tests are included, or existing tests cover the modified code (in this case I have detailed which ones those are in the commit message).
- My commit message includes data points confirming performance improvements (if claimed).
- My PR is restricted to a single feature or bugfix.
- White-space or formatting changes outside the feature-related changed lines are in commits of their own.
Now let's run the following command to let JBMC tell us about potential errors | ||
in our `query` method. | ||
``` | ||
jbmc Example.class --function core.Example.query |
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.
That's a bit strange that you cd
first into core
and then run jbmc
from there. I'd say jbmc core/Example.class ...
.
Side note: At some point that will actually change to running jbmc core.Example ...
(akin to java core.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.
Is core
a good name? What about tutorial
or examples
?
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.
Actually, about your first comment, I'm not cd-ing into anything. There is no core
folder. I compiled the java file using javac
, and it's not within a maven project, so the folder hierarchy doesn't follow the packages. Is that confusing? Should I remove the package from the examples?
|
||
\subsection jbmc-manual-unwind Loop unwinding | ||
|
||
As in CBMC, JBMC transforms the input program into a state representation, |
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.
As CBMC, JBMC
\subsection jbmc-manual-unwind Loop unwinding | ||
|
||
As in CBMC, JBMC transforms the input program into a state representation, | ||
and thus needs to unwind loops up to a given value. Without specifying a |
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.
an unwind
To limit the number of times the for-loop is unwound, we use the `--unwind N` | ||
options, in which case the following call to JBMC: | ||
``` | ||
jbmc Example.class --function core.Example.isPrime --unwind 10 |
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.
core/
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.
🔧
To be sure that this always holds, we run JBMC on the example, with a | ||
reasonable `unwind` value: | ||
``` | ||
jbmc Example.class --function core.Example.isPrime --unwind 10 |
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.
core/
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 we make our code more robust by adding guards to make the array access | ||
safe as follows: | ||
```java | ||
5 public static int query(int[] array, int index) { |
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 suggest to make the examples complete classes with different names so that the user can easily copy paste the code and run.
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
``` | ||
[java::core.Example.doSomething:()V.assertion.1] line 8 assertion: FAILURE | ||
``` | ||
Again, the trace shows the contradicting string: |
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.
to be precise "the string violating the condition in the assertion"
|
||
JBMC has a wealth of other options that can either constrain the model (to | ||
cope with complexity issues), or output more relevant information. The list | ||
of all available options are printed by typing: |
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.
is printed
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.
by running
|
||
To remove all the assertions checking for uncaught exceptions, the | ||
`--disable-uncaught-exception-check` can be used in combination with | ||
`--throw-runtime-exceptions`. |
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 might be worth pointing out that in the JVM assert
actually throws an AssertionError on violation. Thus it can be handled like any other 'exception' (Throwable, to be precise). This behaviour can be enabled with --throw-assertion-error
. An assertion violation is then reported as an uncaught 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.
Added this
Rerunning the analysis with the `--trace` option, we can see find out which | ||
input value JBMC found to trigger the violation: | ||
``` | ||
INPUT arg0i: 15 |
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.
To getter better variable names, compile with -g
and explain this.
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
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.
✔️
Passed Diffblue compatibility checks (cbmc commit: a58697f).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/91258287
a58697f
to
479e45d
Compare
@peterschrammel this is ready for re-review. Note for reviewers: since |
``` | ||
package tutorial; | ||
|
||
public class Example2 |
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.
Missing {
Rerunning the analysis with the `--trace` option, we can see find out which | ||
input value JBMC found to trigger the violation: | ||
|
||
INPUT inputVal: 15 |
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.
When I run jbmc Example3.class --function tutorial.Example3.doSomething --unwind 10 --trace
, I did not see INPUT inputVal: 15
but it shows me ```Violated property:
file tutorial/Example3.java function tutorial.Example3.doSomething(int) line 6 thread 0
assertion at file tutorial/Example3.java line 6 function java::tutorial.Example3.doSomething:(I)V bytecode-index 16
false
** 1 of 15 failed (2 iterations)
VERIFICATION FAILED
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.
Don't you see something like this in the trace view? I rephrased the doc a bit to suggest that it needs a bit of searching.
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.
Actually now I see INPUT inputVal: 15 (00000000 00000000 00000000 00001111)
, so now it is good.
The value chosen by JBMC is arbitrary, and could as well be 9 | ||
or 2084569161. | ||
Note that to see the original parameter names in the trace | ||
output, the java source must be compiled in debug mode (`javac -g`). |
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 tried javac -g
but but I could not find the original parameter names...
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.
That's weird. I'll have a look at this on your machine.
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 also resolved.
|
||
In the following code, only with `--throw-runtime-exceptions` will JBMC | ||
signal that the assertion on line 11 can be violated. Without that option, | ||
line 11 will be considered as unreachable, and hence the assertion to be valid. |
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 maybe nice to tell how jbmc thinks the line is unreachable from the log. Also without --throw-runtime-exception
, I still get different Failure
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 can't actually see that in the output. JBMC doesn't tell us which parts of the bytecode it managed to reach.
479e45d
to
7905eed
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.
🚫
This PR failed Diffblue compatibility checks (cbmc commit: 479e45d).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/91407736
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).
The incompatibility may have been introduced by an earlier PR. In that case merging this
PR should be avoided unless it fixes the current incompatibility.
@yumibagge comments applied/responded to. |
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.
✔️
Passed Diffblue compatibility checks (cbmc commit: 7905eed).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/91414593
a197cd6
to
83c4929
Compare
@yumibagge from your offline comments:
|
83c4929
to
41f3a43
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.
🚫
This PR failed Diffblue compatibility checks (cbmc commit: a197cd6).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/91499218
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).
The incompatibility may have been introduced by an earlier PR. In that case merging this
PR should be avoided unless it fixes the current incompatibility.
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.
✔️
Passed Diffblue compatibility checks (cbmc commit: 41f3a43).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/91507626
Now let's run the following command to let JBMC tell us about potential errors | ||
in our `query` method. | ||
|
||
$ jbmc ExampleArray.class --function tutorial.ExampleArray.query |
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.
tutorial/ExampleArray.class
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.
As mentioned in a previous comment, there is no tutorial
folder. We're not in a Maven project. If you just use javac
on a java file (which is the approach chosen in this tutorial), you get a class file in the same directory. 🔧
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.
But this is not the way java
works. You cannot run java ExampleArray
, you must use java tutorial.ExampleArray
. JBMC will work the same way soon. We can apply a simple 's#jbmc tutorial/ExampleArray.class#jbmc tutorial.ExampleArray' to this tutorial after this change.
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.
OK, got it. That makes sense now. I now consider the class file to be in a folder named after the package.
In brief, JBMC creates a model from Java Bytecode (given as input as a .class | ||
file or a .jar) and performs static analysis and symbolic simulation which allow | ||
to prove or refute properties. These properties are either automatically | ||
generated, or provided by the user in the form of assertions. |
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.
automatically generated (runtime errors)
|
||
In brief, JBMC creates a model from Java Bytecode (given as input as a .class | ||
file or a .jar) and performs static analysis and symbolic simulation which allow | ||
to prove or refute properties. These properties are either automatically |
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.
allow us to prove
largely applies to JBMC. | ||
|
||
In brief, JBMC creates a model from Java Bytecode (given as input as a .class | ||
file or a .jar) and performs static analysis and symbolic simulation which allow |
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.
symbolic 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.
I just re-used the wording from the CBMC tutorial. But will follow your suggestion.
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.
Ah... I think execution is more common, though.
|
||
\subsection jbmc-manual-unwind Loop unwinding | ||
|
||
As CBMC, JBMC transforms the input program into a state representation, |
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 'state representation' is something intuitively understood by the reader.
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.
removing this part of the sentence
|
||
\section jbmc-tutorial JBMC tutorial | ||
|
||
\subsection jbmc-manual-auto-assert Automatic assertions |
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.
Jbmc can detect two things: A. thrown exceptions/errors or B. uncaught exceptions/errors.
Orthogonally, there are 3 groups of errors that we want to detect:
- Assertion violations
- Runtime exceptions
- Explicit throws
The question is how best to introduce it. B2, B3 are probably the concepts Java developers are most familiar with. A is a bit more for experts and probably best explained for 2 (as you do).
For people familiar with assertions starting with A1 would be doable. The difference between A1 and B1 is for practical purposes irrelevant (unless you catch AssertionError somewhere).
In the long term I'd like to make B the default behaviour.
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 do you want me to do here? Shall I enumerate these groups in the introduction?
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 have to restructure the sections a bit to start with familiar concepts and then go to less familiar ones. But we can do this in a second iteration.
To limit the number of times the for-loop is unwound, we use the `--unwind N` | ||
options, in which case the following call to JBMC: | ||
|
||
$ jbmc ExampleUnwind.class --function tutorial.ExampleUnwind.isPrime --unwind 10 |
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.
tutorial/ExampleUnwind.class
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.
🔧
2| | ||
3| public class ExampleArray { | ||
4| | ||
5| public static int query(int[] array, int index) { |
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 might be worth changing this to static void main(String[]) to show also the case without --function option
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 think it's slightly confusing to start with the example where the entry point is main, because the reader needs to understand that the entry point is always a function, and that main
is only the default. So I change one of the later examples (the one with models). Furthermore, that example is better suited to be a main because we don't use any arguments.
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 is very intuitive that the entry point is main
because this is how you run a Java program. You can then explain that you can choose other methods entry point (which is unlike java
).
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.
That's right I'll try to start with an example with main
as entry point then.
Rerunning the analysis with the `--trace` option, the following line appears | ||
somewhere in the trace output and tells us which input value JBMC found to | ||
trigger the violation (note that to see the original parameter names in the | ||
trace output, the java source must be compiled in debug mode: `javac -g`): |
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.
Java source
@peterschrammel changes applied. What would you like me to do about the 🔧 (folder of class files) issue? I could remove the package altogether, but I thought it would be good to show the syntax of |
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.
✔️
Passed Diffblue compatibility checks (cbmc commit: c7b714d).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/91561535
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.
✔️
Passed Diffblue compatibility checks (cbmc commit: c94494e).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/91640253
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.
Let's go with that
c94494e
to
63c944c
Compare
@peterschrammel I have made some improvements. Do you want to take a look? |
[java::tutorial.ExampleExceptions.strLength:(Ljava/lang/String;)I.1] line 6 no uncaught exception: FAILURE | ||
``` | ||
This could be fixed by adding a try-catch statement, or else checking that | ||
`str` is non-Null before accessing it. |
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.
⛏ non-null
@allredj, please squash the commits |
ab18976
to
00ac7b8
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.
🚫
This PR failed Diffblue compatibility checks (cbmc commit: ab18976).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/91656682
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).
The incompatibility may have been introduced by an earlier PR. In that case merging this
PR should be avoided unless it fixes the current incompatibility.
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.
✔️
Passed Diffblue compatibility checks (cbmc commit: 00ac7b8).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/91657894