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

1.23 2.0 acw/focus-triggers main test-branch
Last change on this file since 869af89 was 5d390d68, checked in by Stephen Siegel <siegel@…>, 12 years ago

Updated manual, refining instructions on installation and adding Z3.

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

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