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

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

Updating instructions, User Manual

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

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