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

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

Cleaned up all problems with manual, got book marks right, table
of contents right, got rid of all warnings.

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

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