1
- \ingroup module_hidden
2
- \page jbmc-user-manual JBMC User Manual
1
+ [ CPROVER Manual TOC] ( ../ )
3
2
3
+ # Verifying Java with JBMC
4
4
5
- \section jbmc-manual-intro Introduction
5
+ ## Introduction
6
6
7
7
JBMC is a bounded model checking tool for the Java language. It follows the
8
8
same principles as CBMC, thus the existing
9
- [ documentation for CBMC] ( http://www.cprover.org/cprover-manual/ cbmc.html )
9
+ [ documentation for CBMC] ( ../ cbmc/tutorial/ )
10
10
largely applies to JBMC.
11
11
12
- In brief, JBMC creates a model from Java Bytecode (given as input as a .class
13
- file or a .jar) and performs static analysis and symbolic execution which allow
14
- us to prove or refute properties. These properties are either automatically
15
- generated (runtime errors), or provided by the user in the form of assertions.
12
+ In brief, JBMC creates a model from Java Bytecode (given as input as a
13
+ ` .class ` file or a ` .jar ` ) and performs static analysis and symbolic
14
+ execution which allow us to prove or refute properties. These properties
15
+ are either automatically generated (runtime errors), or provided by the user
16
+ in the form of assertions.
16
17
17
18
Using examples, the following section will guide you through the basic
18
19
features of JBMC.
19
20
21
+ ## JBMC tutorial
20
22
21
- \section jbmc-tutorial JBMC tutorial
22
-
23
- \subsection jbmc-manual-auto-assert Automatic assertions
23
+ ### Automatic assertions
24
24
25
25
Consider the following simplistic ` ExampleArray.java ` file which we have
26
26
compiled into ` tutorial/ExampleArray.class ` and which queries the array of
@@ -40,11 +40,12 @@ input arguments at index 3:
40
40
41
41
Now let's run the following command to let JBMC tell us about potential errors
42
42
in our program.
43
-
44
- $ jbmc tutorial/ExampleArray.class
43
+ ```
44
+ $ jbmc tutorial/ExampleArray.class
45
+ ```
45
46
46
47
The output contains the following:
47
- ``` c
48
+ ``` plaintext
48
49
[java::tutorial.ExampleArray.main:([Ljava/lang/String;)V.null-pointer-exception.1] line 7 Null pointer check: SUCCESS
49
50
[java::tutorial.ExampleArray.main:([Ljava/lang/String;)V.array-index-out-of-bounds-low.1] line 7 Array index should be >= 0: SUCCESS
50
51
[java::tutorial.ExampleArray.main:([Ljava/lang/String;)V.array-index-out-of-bounds-high.1] line 7 Array index should be < length: FAILURE
@@ -75,20 +76,21 @@ safe as follows:
75
76
13| }
76
77
```
77
78
then when running JBMC on that corrected version:
78
-
79
- $ jbmc tutorial/ExampleArraySafe.class
79
+ ```
80
+ $ jbmc tutorial/ExampleArraySafe.class
81
+ ```
80
82
81
83
all the automatic assertions become valid, meaning that there is no
82
84
possible inputs (argument values) for which they can be violated:
83
- ```c
85
+ ``` plaintext
84
86
[java::tutorial.ExampleArraySafe.main:([Ljava/lang/String;)V.1] line 7 no uncaught exception: SUCCESS
85
87
[java::tutorial.ExampleArraySafe.main:([Ljava/lang/String;)V.null-pointer-exception.1] line 8 Null pointer check: SUCCESS
86
88
[java::tutorial.ExampleArraySafe.main:([Ljava/lang/String;)V.null-pointer-exception.2] line 9 Null pointer check: SUCCESS
87
89
[java::tutorial.ExampleArraySafe.main:([Ljava/lang/String;)V.array-index-out-of-bounds-low.1] line 9 Array index should be >= 0: SUCCESS
88
90
[java::tutorial.ExampleArraySafe.main:([Ljava/lang/String;)V.array-index-out-of-bounds-high.1] line 9 Array index should be < length: SUCCESS
89
91
```
90
92
91
- \subsection jbmc-manual-unwind Loop unwinding
93
+ ## Loop unwinding
92
94
93
95
As CBMC, JBMC needs to unwind loops up to a given value. Consider the ` isPrime `
94
96
method in the code below. Without specifying an unwind limit, JBMC will not
@@ -120,49 +122,49 @@ depends on an input):
120
122
```
121
123
To limit the number of times the for-loop is unwound, we use the ` --unwind N `
122
124
options, in which case the following call to JBMC:
123
-
124
- $ jbmc tutorial/ExampleUnwind.class --function tutorial.ExampleUnwind.isPrime --unwind 10
125
-
125
+ ```
126
+ $ jbmc tutorial/ExampleUnwind.class --function tutorial.ExampleUnwind.isPrime --unwind 10
127
+ ```
126
128
will terminate correctly. In this case, we will see ` VERIFICATION SUCCESSFUL ` ,
127
129
as no automatic assertions are violated.
128
130
129
131
Note that in that example, there are is no main function, so we give specify
130
132
the desired entry point via the ` --function ` option.
131
133
132
134
133
- \subsection jbmc-manual-user-assert User assertions
135
+ ## User assertions
134
136
135
137
Elaborating on the example above, users may provide their own assertions, that
136
138
JBMC will try to refute. On line 7, we check the assertion that all odd
137
139
numbers greater than 1 are prime. To be sure that this always holds, we run
138
140
JBMC on the example, with a reasonable ` unwind ` value:
139
-
140
- $ jbmc tutorial/ExampleUnwind.class --function tutorial.ExampleUnwind.doSomething --unwind 10
141
-
141
+ ```
142
+ $ jbmc tutorial/ExampleUnwind.class --function tutorial.ExampleUnwind.doSomething --unwind 10
143
+ ```
142
144
Unsurprisingly JBMC doesn't agree, and prints an assertion failure
143
145
(truncated here for readability):
144
- ``` c
146
+ ``` plaintext
145
147
[...doSomething:(I)V.assertion.1] line 7 assertion at file tutorial/ExampleUnwind.java: FAILURE
146
148
```
147
149
148
150
Rerunning the analysis with the ` --trace ` option, the following line appears
149
151
somewhere in the trace output and tells us which input value JBMC found to
150
152
trigger the violation (note that to see the original parameter names in the
151
153
trace output, the Java source must be compiled in debug mode: ` javac -g ` ):
152
- ``` c
154
+ ``` plaintext
153
155
INPUT inputVal: 15
154
156
```
155
157
The value chosen by JBMC is arbitrary, and could as well be 9
156
158
or 2084569161.
157
159
158
- \subsection jbmc-manual-library Java Library support
160
+ ## Java Library support
159
161
160
162
The examples above only involve primitive types. In order to analyse code
161
163
involving Java Library classes, the core models (located in the same
162
164
repository) need to be added to the classpath:
163
-
164
- --cp <path_to_cbmc>/jbmc/src/java_bytecode/library/core-models.jar
165
-
165
+ ```
166
+ --cp <path_to_cbmc>/jbmc/src/java_bytecode/library/core-models.jar
167
+ ```
166
168
167
169
The core models library simulate the behavior of the Java Library and
168
170
contains some commonly used classes, such as Object, Class, String, Enum.
@@ -185,21 +187,21 @@ from `java.lang.String`, e.g.
185
187
```
186
188
The following command line (note that the current directory is also added to
187
189
the classpath):
188
-
189
- $ jbmc tutorial/ExampleModels.class --cp <path_to_cbmc>/jbmc/src/java_bytecode/library/core-models.jar:.
190
-
190
+ ```
191
+ $ jbmc tutorial/ExampleModels.class --cp <path_to_cbmc>/jbmc/src/java_bytecode/library/core-models.jar:.
192
+ ```
191
193
will flag this violation (truncated):
192
- ``` c
194
+ ``` plaintext
193
195
[java::tutorial.ExampleModels.stringOp:()V.assertion.1] line 8 assertion: FAILURE
194
196
```
195
197
196
198
Again, the trace (when re-running with ` --trace ` ) shows the string violating
197
199
the condition in the assertion:
198
- ``` c
200
+ ``` plaintext
199
201
dynamic_object2={ 'a', 'b', '$', 'c', 'd' }
200
202
```
201
203
202
- \subsection jbmc-manual-exceptions Exceptions
204
+ ## Exceptions
203
205
204
206
In its analysis, JBMC can take into account exceptions thrown by user code or
205
207
library classes, as well as runtime exceptions such as NullPointerException.
@@ -220,13 +222,12 @@ Consider the following code:
220
222
```
221
223
222
224
When given the ` --throw-runtime-exceptions ` options:
223
-
224
- $ jbmc tutorial/ExampleExceptions --tutorial.ExampleExceptions.strLength --throw-runtime-exceptions
225
-
225
+ ```
226
+ $ jbmc tutorial/ExampleExceptions --tutorial.ExampleExceptions.strLength --throw-runtime-exceptions
227
+ ```
226
228
JBMC will signal that the ` str.length() ` call may throw a runtime exception
227
229
and that this exception is not caught.
228
-
229
- ```c
230
+ ``` plaintext
230
231
[java::tutorial.ExampleExceptions.strLength:(Ljava/lang/String;)I.1] line 6 no uncaught exception: FAILURE
231
232
```
232
233
This could be fixed by adding a try-catch statement, or else checking that
@@ -243,9 +244,9 @@ VERIFICATION SUCCESSFUL
243
244
```
244
245
245
246
When analyzing this function without runtime exception support:
246
-
247
- $ jbmc tutorial/ExampleExceptions
248
-
247
+ ```
248
+ $ jbmc tutorial/ExampleExceptions
249
+ ```
249
250
JBMC only reports the error as a null pointer check failure:
250
251
```
251
252
[...null-pointer-exception.1] line 6 Null pointer check: FAILURE
@@ -258,11 +259,11 @@ on violation. This behavior can be replicated in JBMC by using the
258
259
then be reported like any other uncaught exception.
259
260
260
261
261
- \subsection jbmc-manual-further-doc Further documentation
262
+ ## Further documentation
262
263
263
264
JBMC has a wealth of other options that can either constrain the model (to
264
265
cope with complexity issues), or output more relevant information. The list
265
266
of all available options is printed by running:
266
-
267
- $ jbmc --help
268
-
267
+ ```
268
+ $ jbmc --help
269
+ ```
0 commit comments