Abstract Interpretation Based Program Testing
Total Page:16
File Type:pdf, Size:1020Kb
1 Abstract Interpretation Based Program Testing Patrick Cousot and Radhia Cousot Département d’informatique Laboratoire d’informatique École normale supérieure École polytechnique 45 rue d’Ulm 91128 Palaiseau cedex, France 75230 Paris cedex 05, France [email protected] [email protected] http://lix.polytechnique.fr/˜rcousot http://www.di.ens.fr/˜cousot Abstract— Every one can daily experiment that programs II. An informal introduction to abstract are bugged. Software bugs can have severe if not catas testing trophic consequences in computer-based safety critical ap plications. This impels the development of formal methods, Abstract testing is the verification that the abstract se whether manual, computer-assisted or automatic, for verify mantics of a program satisfies an abstract specification. ing that a program satisfies a specification. Among the auto matic formal methods, program static analysis can be used The origin is the abstract interpretation based static check to check for the absence of run-time errors. In this case the ing of safety properties [1], [2] such as array bound checking specification is provided by the semantics of the program and the absence of run-time errors which was extended to ming language in which the program is written. Abstract in terpretation provides a formal theory for approximating this liveness properties such as termination [3], [4]. semantics, which leads to completely automated tools where Consider for example, the factorial program (the random run-time bugs can be statically and safely classified as un assignment ? is equivalent to the reading of an input value reachable, certain, impossible or potential. We discuss the or the passing of an unknown but initialized parameter extension of these techniques to abstract testing where speci fications are provided by the programmers. Abstract testing value): is compared to program debugging and model-checking. # ITlra.analysis ();; Keywords— Abstract interpretation, Model-checking, De Reachability/ancestry analysis for initial/final states; bugging, Abstraction, Testing, Abstract testing. Type the program to analyze... n:=?; f:=1; while (n <> 0) do f:=(f*n); I. Introduction n:=(n-1) od;; Software debugging represents a large proportion of the The automatic analysis of this factorial program [5], [6] software development and maintenance cost (from 25% up leads to the result below. Each program point has been to 70% for safety critical software). Beyond classical debug numbered and a corresponding local invariant (given be ging methods, code review, simulation, etc., new formal tween parentheses) provides the possible values of the vari methods have been investigated during this past decade ables when reaching that program point. The value , typed such as: _O_, denotes the uninitialized value. Otherwise an inter val of possible values is given for integer variables (with deductive methods : to prove that a program semantics sat ∞ −∞ isfies a user-provided specification (using automatic theo + (respectively )typed+oo (resp. -oo)denotingthe rem provers or interactive proof checkers); greatest (resp. smallest) machine representable integer). model-checking : to check that a (finite) model of the pro The result of the automatic analysis is the following: gram satisfies a user-provided specification (using exhaus 0: { n:_O_; f:_O_ } tive or symbolic state exploration techniques); n:=?; 1:!: { n:[0,+oo]; f:_O_ } static analysis : to verify that no program execution can f:=1; lead to run-time errors as specified by the programming 2: { n:[0,+oo]; f:[1,+oo] } language semantics (by computation of an abstract inter while ((n < 0) | (0 < n)) do 3: { n:[1,+oo]; f:[1,+oo] } pretation of the semantics of the program). f:=(f*n); 4: { n:[1,+oo]; f:[1,+oo] } We investigate abstract testing, an extension of program n:=(n-1) static analysis aiming at verifying user-provided specifica 5: { n:[0,1073741822]; f:[1,+oo] } tions by abstract interpretation of the program semantics. od {(n = 0)} 6: { n:[0,0]; f:[1,+oo] } The technique is a natural extension of program debugging using program properties instead of values. We compare The analysis automatically discovers the condition n ≥ 0 abstract testing to program debugging and model checking. which should be checked at program point 1 (as indicated 2 by :!:), since otherwise a runtime error or nontermination By choosing different user specified invariant assertions is inevitable. Then the computed invariants will always Iv for (¬E) and intermittent assertions It for F ,these hold. For example the final value of n is 0 whereas f ≥ forms of specification were slightly extended by [8] under 1. The analysis is performed for the specific value +∞ = the name “abstract debugging” to: 1073741823 whence n ∈ [0, 1073741822] at program point 5 since otherwise there would have been an overflow so that post[t ] I =⇒ Iv ∧ pre[t ]It . execution would have stopped after that runtime error. If the states p, m∈S consist of a program point p ∈ P III. A formalization of abstract testing and a memory state m ∈ M then the user can specify local invariant assertions Ivp attached to program points Let S, t, I, F, E be a transition system with set of ∈ ⊆ ⊆ × p Pv P and local intermittent assertions Itp attached states S , transition relation t (S S), initial states ∈ I ⊆ S , erroneous states E ⊆ S , and final states F ⊆ S. to program points p Pt so that The transition system is assumed to be generated by a Iv = {p, m|p ∈ Pv =⇒ Ivp(m)} small step operational semantics [7]. and It = {p, m|p ∈ Pt ∧ It (m)} . Example 1 In the factorial example of Sec. II,thestates p are triples p, n, f where p ∈{0,...,6} is a program point, Otherwise stated, the descendants of the initial states al n, f ∈ Z ∪{} are the respective values of variables n and ways satisfy all local invariant assertions (which always f. The initial states are I = {0,,}. The final states are holds) and can potentially lead to states satisfying some lo F = {6,n,f|n, f ∈ Z ∪ {}}. The erroneous states are cal intermittent assertion (which will sometime hold). For E = {p, n, f|n ∈ [−∞, +∞] ∨ f ∈ [−∞, +∞]},thatis example, a specification that the above factorial program the value of the integer variables is out of bounds. Writing should always terminate normally states that any execu t s −→ s for s, s∈t,wehave: tion should always reach program point 6 hence would consist in choosing: 0,n,f −→t 1,z,f,z∈ Z Ivp(n, f)=n, f ∈ [−∞, +∞],p= 1,...,6; 1,n,f −→t 2,n,1 Itp(n, f)=false,p= 1,...,5; 2,n,f −→t 3,n,f if n ∈ Z \{0} It6(n, f)=true . 2, 0,f −→t 6, 0,f The termination requirement can be very simply specified t 3,n,f −→ 4,n,f.n as comments in the program text: t 4,n,f −→ 5,n− 1,f 0: n := ?; t 1: f := 1; 5,n,f −→ 2,n,f 2: while ((n < 0) | (0 < n)) do 3:f:=(f*n); A program execution is a finite or infinite sequence 4:n:=(n-1) σ ...σ ... of states σ ∈ S. Execution starts with an 5: od; 0 i i 6: sometime true;; initial state σ0 ∈ I.Anystateσi is related to its succes sor state σi+1 as specified by the transition relation t so or by using an external temporal specification such as that σi,σi+1∈t. The sequence is finite σ0 ...σi ...σn ✸ at 6 (we use the temporal operators ✷ P (read always if and only if the last state is erroneous σn ∈ E (because P ) to denote the set of sequences of states such that all of an anomaly during execution) or final σn ∈ F (because states satisfy P , ✸ P (read sometime P )todenotetheset of normal termination). All other states have a successor of sequences containing at least one state satisfying P and in which case execution goes on normally, may be for ever the predicate at p holds in all states which control point is (formally ∀s ∈ S \ (E ∪ F ):∃s ∈ S : s, s∈t). p). Let t−1 be the inverse of relation t.Lett be the reflex A program static analyzer can therefore be used for ab ive transitive closure of the binary relation t.Letpost[t] X stract testing which is similar to testing/debugging, with be the post-image of X by t, that is the set of states some essential differences such as the consideration of an which are reachable from a state of X by a transition t: abstract semantics instead of a concrete one, the ability to post[t] X def= {s ∈ S |∃s ∈ X : s, s∈t} [2], [4]. Inversely, consider several (reversed) executions at a time (as speci def − fied by user initial and final state specifications), the use of let pre[t] X =post[t 1] X be the pre-image of X by t that forward and backward reasonings, the formal specification is the set of states from which there exists a possible tran of what has to be tested, etc. sition t to a state of X:pre[t] X = {s ∈ S |∃s ∈ X : s, s ∈t}. The specifications considered in [3]areofthe IV. Model-checking of temporal specifications form: post[t] I =⇒ (¬E) ∧ pre[t] F. At first sight, abstract testing is model-checking [9], [10] of the temporal formula: Informally such a specification states that the descendants of the initial states are never erroneous and can potentially ✷( atp =⇒ Ivp) ∧ ✸( atp ∧Itp) lead to final states. p∈Pv p∈Pt 3 for a small-step operational semantics S, t, I of the pro from the user sometimes amounting to a full manual proof. gram, or more precisely, abstract model-checking [11], [12] since abstract interpretation is involved.