source: CIVL/doc/manual/part-introduction.tex@ dccd621

1.23 2.0 main test-branch
Last change on this file since dccd621 was 536af01, checked in by Stephen Siegel <siegel@…>, 11 years ago

Simplification of installation instructions in README and manual.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@1793 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 16.3 KB
Line 
1\part{Introduction}
2\label{part:intro}
3
4\chapter{Acknowledgement}
5
6The CIVL project is funded by the U.S.\ National Science Foundation
7under awards CCF-1346769 and CCF-1346756.
8
9\chapter{What is CIVL?}
10
11\textbf{CIVL} stands for \emph{Concurrency Intermediate Verification
12 Language}. The \emph{CIVL platform} encompasses:
13\begin{enumerate}
14\item the programming language \textbf{CIVL-C}, a dialect of C with
15 additional primitives supporting concurrency, specification, and modeling;
16\item verification and
17 analysis tools, including a symbolic execution-based model checker for
18 checking various properties of, or finding defects in, CIVL-C
19 programs; and
20\item tools that translate from many commonly used
21 languages/APIs to CIVL-C.
22\end{enumerate}
23
24The CIVL-C language is primarily intended to be an intermediate
25representation for verification. A C program using
26MPI~\cite{mpi-forum:2012:mpi30}, CUDA~\cite{cuda-programming-guide},
27OpenMP~\cite{openmp-standard}, OpenCL~\cite{opencl-standard}, or
28another API (or even some combination of APIs), will be automatically
29translated into CIVL-C and then verified. The advantages of such a
30framework are clear: the developer of a new verification technique
31could implement it for CIVL-C and then immediately see its impact
32across a broad range of concurrent programs. Likewise, when a new
33concurrency API is introduced, one only needs to implement a
34translator from it to CIVL-C in order to reap the benefits of all the
35verification tools in the platform. Programmers would have a valuable
36verification and debugging tool, while API designers could use CIVL as
37a ``sandbox'' to investigate possible API modifications, additions,
38and interactions.
39
40This manual covers all aspects of the CIVL framework, and is organized in parts
41as follows:
42\begin{enumerate}
43\item this introduction, including ``quick start'' instructions for
44 downloading and installing CIVL and several examples;
45\item a complete description of the CIVL-C language;
46\item a formal semantics for the language; and
47\item a description of the tools in the framework.
48\end{enumerate}
49
50\chapter{Installation and Quick Start}
51
52This chapter gives instructions for downloading and installing CIVL,
53and running the verification tool on an example.
54
55\subsection*{Notes}
56
57\begin{itemize}
58\item The instructions say to install three theorem provers. In
59 reality, each of these is optional. CIVL will still work without
60 any theorem provers, but the results will not be very precise, i.e.,
61 it will produce a lot of false warnings. The more provers you
62 install, the more precise the analysis.
63\end{itemize}
64
65\subsection*{Instructions}
66
67\begin{enumerate}
68\item Install the automated theorem prover CVC3 (if you have not
69 already). The easiest way to do this is to visit
70 \url{http://www.cs.nyu.edu/acsys/cvc3/download.html} and download
71 the latest, optimized build with static library and executable for
72 your OS. Place the executable file \texttt{cvc3} somewhere in your
73 \texttt{PATH}. You can discard everything else. Alternatively, on
74 some linux systems, CVC3 can be installed using the package manager
75 via ``\texttt{sudo apt-get install cvc3}''. This will place
76 \texttt{cvc3} in \texttt{/usr/bin}.
77
78\item Install the automated theorem prover CVC4 (if you have not
79 already). The easiest way to do this is to visit
80 \url{http://cvc4.cs.nyu.edu/downloads/} and choose one of the
81 installation approaches. You only need the binary (\texttt{cvc4}),
82 and you must put it in your \texttt{PATH}. Alternatively, on OS X
83 you may install using MacPorts by ``\texttt{sudo port install
84 cvc4}''.
85
86\item Install the automated theorem prover Z3 (if you have not
87 already). Follow instructions at
88 \url{http://z3.codeplex.com/SourceControl/latest#README}. Make sure
89 the executable \texttt{z3} is in your path.
90
91\item Install a Java 7 SDK if you have not already. Go to
92 \url{http://www.oracle.com/technetwork/java/javase/downloads/} for
93 the latest from Oracle. On linux, you can instead use the package
94 manager: ``\texttt{sudo apt-get install openjdk-7-jdk}''.
95
96\item Download and unpack the latest stable release of CIVL from
97 \url{http://vsl.cis.udel.edu/civl}.
98
99\item The resulting directory should be named
100 \texttt{CIVL-\textit{tag}} for some string \textit{tag} which
101 identifies the version of CIVL you downloaded. Move this directory
102 wherever you like.
103
104\item The JAR file in the \texttt{lib} directory is all you need to
105 run CIVL. You may move this JAR file wherever you want. You run
106 CIVL by typing a command of the form ``\texttt{java -jar
107 /path/to/civl-TAG.jar ...}''. For convenience, you may instead
108 use the shell script \texttt{civl} included in the \texttt{bin}
109 directory. This allows you to replace ``\texttt{java -jar
110 /path/to/civl-TAG.jar}'' with just ``\texttt{civl}'' on the
111 command line. Simply edit the \texttt{civl} script to reflect the
112 path to the JAR file and place the script somewhere in your
113 \texttt{PATH}. Alternatively, you can define an alias in your
114 \texttt{.profile}, \verb!.bash_profile!, \texttt{.bashrc}, or
115 equivalent, such as
116\begin{verbatim}
117alias civl='java -jar /path/to/civl-TAG.jar'
118\end{verbatim}
119 In the following, we will assume that you have defined a command
120 \texttt{civl} in one of these ways.
121
122\item From the command line, type ``\texttt{civl help}''. You should see
123 a help message describing the command line syntax.
124
125\item From the command line, type ``\texttt{civl config}''. This should
126 report that \texttt{cvc3}, \texttt{cvc4}, and \texttt{z3} were
127 found, and it should create a file called \texttt{.sarl} in your
128 home directory.
129
130\end{enumerate}
131
132To test your installation, copy the file
133\texttt{examples/concurrency/locksBad.cvl} to your working directory.
134Look at the program: it is a simple 2-process program with two shared
135variables used as locks. The two processes try to obtain the locks in
136opposite order, which can lead to a deadlock if both processes obtain
137their first lock before either obtains the second. Type
138``\verb!civl verify locksBad.cvl!''. You should see some output
139culminating in a message
140\begin{verbatim}
141The program MAY NOT be correct. See CIVLREP/locksBad_log.txt
142\end{verbatim}
143
144Type ``\verb!civl replay locksBad.cvl!''. You should see a
145step-by-step account of how the program arrived at the deadlock.
146
147
148\chapter{Examples}
149
150In this section we show a few simple CIVL-C programs which illustrate
151some of the pertinent features of the language. We also show the results
152of running some of the tools on them.
153
154\section{Dining Philosophers}
155
156Dijkstra's well-known Dining Philosophers system can be encoded in
157CIVL-C as shown in Figure \ref{fig:dining}.
158
159\begin{figure}[t]
160 \begin{small}
161\begin{verbatim}
162#include <civlc.h>
163
164$input int B; // upper bound on number of philosophers
165$input int n; // number of philosophers
166$assume 2<=n && n<=B;
167_Bool forks[n]; // Each fork will be on the table (0) or in a hand (1).
168
169void dine(int id) {
170 int left = id;
171 int right = (id + 1) % n;
172
173 while (1) {
174 $when (forks[left] == 0) forks[left] = 1;
175 $when (forks[right] == 0) forks[right] = 1;
176 forks[right] = 0;
177 forks[left] = 0;
178 }
179}
180
181void main() {
182 for (int i = 0; i < n; i++) forks[i] = 0;
183 for (int i = 0; i < n; i++) $spawn dine(i);
184}
185\end{verbatim}
186 \end{small}
187 \caption{\texttt{diningBad.cvl}: CIVL-C encoding of Dijkstra's Dining Philosophers}
188 \label{fig:dining}
189\end{figure}
190
191In this encoding, an upper bound \ct{B} is placed on the number of
192philosophers \ct{n}. When verifying this program, a concrete value
193will be specified for \ct{B}. Hence the result of verification will
194apply to all \ct{n} between $2$ and \ct{B}, inclusive.
195
196Both \ct{B} and \ct{n} are delcared as \emph{input} variables using
197the type qualifier \cinput. An input variable may be
198initialized with any valid value of its type. In contrast, non-input
199variables declared in file scope will be initialized with a
200special \emph{undefined} value; if such a variable is read before it
201is defined, an error will be reported. In addition, any input variable
202may have a concrete initial value specified on the command line. In
203this case, we will specify a concrete value for \ct{B} on the command
204line but leave \ct{n} unconstrained.
205
206An $\cassume$ statement restricts the set of executions of the program
207to include only those traces in which the assumptions hold. In
208contrast with an $\cassert$ statement, CIVL does not check that the
209assumed expression holds, and will not generate an error message if it
210fails to hold. Thus an $\cassume$ statement allows the programmer to
211say to CIVL ``assume that this is true,'' while an $\cassert$
212statement allows the programmer to say to CIVL ``check that this is
213true.''
214
215A $\cwhen$ statement encodes a \emph{guarded command}. The $\cwhen$
216statement includes a boolean expression called the \emph{guard} and a
217statement body. The $\cwhen$ statement is enabled if and only if the
218\emph{guard} evaluates to \emph{true}, in which case the body may be
219executed. The first atomic statement in the body executes atomically
220with the evaluation of the guard, so it is guaranteed that the guard
221will hold when this initial sub-statement executes. Since assignment
222statements are atomic in CIVL, in this example the bodiy of each
223$\cwhen$ statement executes atomically with the guard evaluation.
224
225The $\cspawn$ statement is very similar to a function call. The main
226difference is that the function called is invoked in a new process
227which runs concurrently with the existing processes. The $\cspawn$
228statement itself returns immediately.
229
230The program may be verified for an upper bound of $5$ by typing the
231following at the command line:
232\begin{verbatim}
233 civl verify -inputB=5 diningBad.cvl
234\end{verbatim}
235
236The output indicates that a deadlock has been found and a
237counterexample has been produced and saved. We can examine the
238counterexample, but it is more helpful to work with a \emph{minimal}
239counterexample, i.e., a deadlocking trace of minimal length. To find a
240minimal counterexample, we issue the command
241
242\begin{verbatim}
243 civl verify -inputB=5 -min diningBad.cvl
244\end{verbatim}
245
246\begin{figure}[t]
247 \begin{small}
248\begin{verbatim}
249CIVL v0.15 of 2014-12-23 -- http://vsl.cis.udel.edu/civl
250Error 0 encountered at depth 129:
251...
252Error 25 encountered at depth 16:
253CIVL execution error (kind: DEADLOCK, certainty: PROVEABLE)
254A deadlock is possible:
255 Path condition: true
256 Enabling predicate: false
257ProcessState 0: terminated
258ProcessState 1: at location 26, f0:21.30-42 "forks[right]"
259 Enabling predicate: false
260ProcessState 2: at location 26, f0:21.30-42 "forks[right]"
261 Enabling predicate: false
262at f0:21.30-42 "forks[right]".
263State 664
264| Path condition
265| | true
266| Dynamic scopes
267| | dyscope 0 (parent=-1, static=0)
268| | | reachers = {1,2}
269| | | variables
270| | | | __atomic_lock_var = process<-1>
271| | | | B = 5
272| | | | n = 2
273| | | | forks = X_s0v4[0:=1, 1:=1]
274...
275| Process states
276...
277| | process 2
278| | | atomicCount = 0
279| | | call stack
280| | | | Frame[function=dine, location=25, f0:21.30-42 "forks[right]", scope=3]
281...
282=================== Stats ===================
283 validCalls : 15327
284 proverCalls : 17
285 memory (bytes) : 18554880
286 time (s) : 2.17
287 maxProcs : 6
288 statesInstantiated : 9264
289 statesSaved : 665
290 statesSeen : 1758
291 statesMatched : 1177
292 steps : 2993
293 transitions : 2934
294
295The program MAY NOT be correct. See CIVLREP/diningBad_log.txt
296\end{verbatim}
297 \end{small}
298 \caption{Output from \texttt{civl verify -inputB=5 -min diningBad.cvl}}
299 \label{fig:diningOut}
300\end{figure}
301
302The result of this command is shown in Figure \ref{fig:diningOut}. The
303output indicates that a minimal counterexample has length 19, i.e.,
304involves 20 states and 19 transitions (the depth of 20 is one more
305than 19). It was the 26th and shortest trace found. It was deemed
306equivalent to the earlier traces and hence the earlier ones were
307discarded and only this one saved. We can replay the trace with the command
308\begin{verbatim}
309 civl replay diningBad.cvl
310\end{verbatim}
311
312\begin{figure}
313 \begin{small}
314\begin{verbatim}
315...
316Transition 1: State 0, proc 0:
317 0->1: B = 5 at f0:9.0-12 "$input int B";
318 1->2: n = InitialValue(n) at f0:10.0-12 "$input int n";
319 2->3: $assume ((2<=n)&&(n<=B)) at f0:11.0-20 "$assume 2<=n && n ... B";
320 3->5: forks = InitialValue(forks) at f0:13.0-12 "int forks[n]";
321 5->6: i = 0 at f0:28.7-16 "int i = 0";
322--> State 1
323
324Transition 2: State 1, proc 0:
325 6->8: LOOP_TRUE_BRANCH at f0:28.18-23 "i < n";
326--> State 2
327
328...
329
330Transition 12: State 12, proc 2:
331 18->19: left = id at f0:16.2-15 "int left = id";
332 19->20: right = ((id+1)%n) at f0:17.2-26 "int right = (id ... n";
333--> State 13
334
335Transition 13: State 13, proc 2:
336 20->23: LOOP_TRUE_BRANCH at f0:19.9-10 "1";
337--> State 14
338
339Transition 14: State 14, proc 1:
340 23->25: forks[left] = 1 at f0:20.29-44 "forks[left] = 1";
341--> State 15
342
343Transition 15: State 15, proc 2:
344 23->25: forks[left] = 1 at f0:20.29-44 "forks[left] = 1";
345--> State 16
346...
347Violation of Deadlock found in State 16:
348A deadlock is possible:
349 Path condition: true
350 Enabling predicate: false
351ProcessState 0: terminated
352ProcessState 1: at location 25, f0:21.30-42 "forks[right]"
353 Enabling predicate: false
354ProcessState 2: at location 25, f0:21.30-42 "forks[right]"
355 Enabling predicate: false
356
357Trace ends after 15 transitions.
358Violation(s) found.
359...
360\end{verbatim}
361 \end{small}
362 \caption{Output from \texttt{civl replay diningBad.cvl}}
363 \label{fig:diningReplay}
364\end{figure}
365
366The result of this command is shown in Figure \ref{fig:diningReplay}.
367The output indicates that a deadlock has been found involving 2
368philosophers. The trace has 15 transitions; after the initialization
369sequence, each philosopher picks up her left fork.
370
371\section{A Multithreaded MPI Example}
372
373\begin{figure}[t]
374 \begin{small}
375\begin{verbatim}
376#include<civlc.h>
377#define TAG 0
378#define NPROCS 2
379#define NTHREADS 2
380
381$gcomm gcomm = $gcomm_create($here, NPROCS);
382
383void MPI_Process (int rank) {
384 $comm comm = $comm_create($here, gcomm, rank);
385 $proc threads[NTHREADS];
386
387 void Thread(int tid) {
388 int x = rank;
389 $message in, out = $message_pack(rank, 1-rank, TAG, &x, sizeof(int));
390
391 for (int j=0; j<2; j++) {
392 if (rank == 1) {
393 for (int i=0; i<2; i++) $comm_enqueue(comm, out);
394 for (int i=0; i<2; i++) in = $comm_dequeue(comm, 1-rank, TAG);
395 } else {
396 for (int i=0; i<2; i++) in = $comm_dequeue(comm, 1-rank, TAG);
397 for (int i=0; i<2; i++) $comm_enqueue(comm, out);
398 }
399 }
400 }
401
402 for (int i=0; i<NTHREADS; i++) threads[i] = $spawn Thread(i);
403 for (int i=0; i<NTHREADS; i++) $wait(threads[i]);
404 $comm_destroy(comm);
405}
406
407void main() {
408 $proc procs[NPROCS];
409
410 for (int i=0; i<NPROCS; i++) procs[i] = $spawn MPI_Process(i);
411 for (int i=0; i<NPROCS; i++) $wait(procs[i]);
412 $gcomm_destroy(gcomm);
413}
414\end{verbatim}
415 \end{small}
416 \caption{\texttt{mpi-pthreads.cvl}: CIVL-C model of a (defective)
417 multithreaded MPI program.}
418 \label{fig:mpithreads}
419\end{figure}
420
421Figure \ref{fig:mpithreads} is an example of a CIVL-C model of
422multithreaded MPI program. The program consists of two processes,
423each of which spawns two threads. All four threads issue
424message-passing operations.
425
426This example illustrates some of the message-passing primitives
427provided in CIVL-C. A \emph{global communicator} object is allocated
428in the root scope. The constant $\chere$ has type $\cscope$ and
429refers to the scope in which the expression occurs; in this case it is
430the root (i.e., file) scope. This global communicator is declared to
431have \texttt{NPROCS} \emph{places}; these are points from which
432messages can be sent or received. The function \verb!MPI_Process! is
433used to model an MPI process. Each instance will create its own
434\emph{local communicator} object which specifies the global
435communicator and a place; this is the object that will be used to send
436or receive messages at that place.
437
438Each process spawns two instances of function \texttt{Thread}. Each
439thread creates a message object from a buffer, specifying the source
440and destination places, tag, pointer to the beginning of the buffer,
441and the size of the buffer. The message is \emph{enqueued} into the
442communication universe using the local communicator. Similarly,
443messages are dequeued by specifying the local communicator, source
444place, and tag.
445
446The program has a subtle defect, which only manifests on very specific
447interleavings of the threads. This defect can be found using
448\texttt{civl verify}.
449
450
Note: See TracBrowser for help on using the repository browser.