970 likes | 983 Views
Explore Proof Generation, Model Abstraction, and Decision Procedures for Ensuring Software Safety.
E N D
Proofs and Counterexamples RupakMajumdar
In the good old days… Decision Procedure yes no
Now… Invariant Generation Model Predicate Abstraction Decision Procedure Pre- Process yes no Proof Interpolant + , - Boolean SAT Sooh, short answer: yes with an if, long answer, no with a but. –Reverend Lovejoy
It’s the Application! • Validating large scale software w.r.t. partial specifications • Rules in documentation • Order of operations & data access • Resource management • Incomplete, unenforced, wordy • Violated rules ) bad behavior • System crash or deadlock • Unexpected exceptions • Failed runtime checks
lock unlock unlock lock Property: Double Locking “An attempt to re-acquire an acquired lock or release a released lock will cause a deadlock.” Calls to lock and unlock must alternate.
lock unlock unlock lock Example Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4: } while(new != old); 5: unlock (); return; } Does program Example satisfy the locking spec?
Ok, but what does this have to do with Invariant Generation Model Predicate Abstraction Decision Procedure Decision Procedure Pre- Process yes yes vs no no Proof Interpolant + , - Boolean SAT
Automatic Verification of Programs Yes Safe Search Program [POPL 02] Automatic Tool Refine No Property [POPL 04] Trace Model and analyze program behavior in the language of logic, reduce reasoning about programs to reasoning about logic
pc lock old new q 3 5 5 0x133a pc lock old new q 4 5 6 0x133a What a program really is… State Transition 3: unlock(); new++; 4:} … Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4: } while(new != old); 5: unlock (); return;}
The Safety Verification Problem Error Safe Initial Is there a path from an initial to an error state ? Problem:Infinitestate graph Solution : Set of states ' logical formula
Representing States asFormulas • [F] • states satisfyingF {s | s² F } • F • FO fmla over prog. vars • [F1] Å [F2] • F1ÆF2 • [F1] [ [F2] • F1 ÇF2 • [F] • : F • [F1] µ [F2] • F1 implies F2 • i.e. F1Æ: F2 unsatisfiable
Idea 1: Symbolic Analysis Error Initial Program State Space Given F, and a program operation, describe a formula for the set of successor states “Strongest postcondition” 2. Iterate the SP, checking at each stage if Erroris hit, or if new states are added
Idea 1: Symbolic Analysis Iterate the SP, checking at each stage if Erroris hit, or if new states are added CurrentReachÆ Error is unsat • OldReachÇSP(OldReach) • CurrentReach Problem: Too many details tracked Symbolic Iteration may not terminate
Idea 1’: Symbolic Analysis + Annotations Ask programmer for Invariant Check Invariant does not hit Error , and Invariant is closed under SP InvariantÆError is unsat • InvariantÇSP(Invariant) • Invariant No more iterations: Programmer provides an inductive assertion, just make two queries Problem: Increased work for the programmer
Idea 2: Predicate Abstraction Error Initial • [Graf-Saidi 97] Abstraction Program State Space • Abstraction: Predicates on program state • Signs: x > 0 • Aliasing: &x &y • States satisfying the same preds are equivalent • Merged into single abstract state
Example: Predicate Abstraction • For the red region above, the predicate abstraction is the set of “boxes” that cover the red region • For each small box , ask the theorem prover if Æ is satisfiable
Idea 2: Predicate Abstraction Abstract • Search finite state space symbolically • Conservative • Abstraction safe ) System safe • Too coarse )spurious counterexample
Idea 3: Counterexample Analysis Abstract Counterexamples: Analyze counterexamples to check feasibility 1. Feasible )BUG Get satisfying assignment from decision procedure: test demonstrating bug
Idea 3: Counterexample Analysis Abstract Counterexamples: Analyze counterexamples to check feasibility 1. Feasible )BUG 2. Infeasible ) What predicates distinguish states across cut? 3. Build refined abstraction
Idea 3: Counterex.-Guided Refinement • [Kurshan et al. 93] • [Clarke et al. 00] • [Ball-Rajamani 01] Abstract Refine • Add predicates to rule out spurious trace • Repeatreachability • Till safe or real trace is found • Or go on refining forever
Idea 3: Counterex.-Guided Refinement Abstract safe Refine • Add predicates to rule out spurious trace • Repeatreachability • Till safe or real trace is found • Or go on refining forever
Problem: Abstraction is Expensive Reachable Problem #abstract states = 2#predicates Exponential Thm. Prover queries • Observe • Fraction of state space reachable • #Preds ~ 100’s, #States ~ 2100 , • #Reach ~ 1000’s
Solution1: Only Abstract Reachable States Solution Build abstraction on-the-fly, during search Problem #abstract states = 2#predicates Exponential Thm. Prover queries
Solution1: Only Abstract Reachable States Solution Build abstraction on-the-fly, during search Problem #abstract states = 2#predicates Exponential Thm. Prover queries
Solution1: Only Abstract Reachable States Solution Build abstraction on-the-fly, during search Problem #abstract states = 2#predicates Exponential Thm. Prover queries
Solution1: Only Abstract Reachable States Safe Solution Build abstraction on-the-fly, during search Problem #abstract states = 2#predicates Exponential Thm. Prover queries
Key Idea: Reachability Tree Initial Unroll Abstraction 1. Pick tree-node (=abs. state) 2. Add children (=abs. successors) 3. On re-visiting abs. state, cut-off 1 2 3 • Counterexample Analysis • Learn new predicates locally • Rebuild subtree with new predicates • “Lazy Abstraction” 5 4 3 [HenzingerJhalaM.Sutre02]
Build-and-Search Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); } 1 : LOCK 1 Reachability Tree Predicates:LOCK
Build-and-Search Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); } 1 : LOCK lock() old = new q=q->next 2 LOCK 1 2 Reachability Tree Predicates:LOCK
Build-and-Search Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); } 1 : LOCK 2 LOCK [q!=NULL] 3 LOCK 1 2 3 Reachability Tree Predicates:LOCK
Build-and-Search Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); } 1 : LOCK 2 LOCK 3 LOCK q->data = new unlock() new++ 4 : LOCK 4 1 2 3 Reachability Tree Predicates:LOCK
Build-and-Search Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); } 1 : LOCK 2 LOCK 3 LOCK 4 : LOCK [new==old] 5 : LOCK 5 4 1 2 3 Reachability Tree Predicates:LOCK
Build-and-Search Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); } 1 : LOCK 2 LOCK 3 LOCK 4 : LOCK 5 : LOCK 5 unlock() 4 : LOCK 1 2 3 Reachability Tree Predicates:LOCK
Analyze Counterexample Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); } 1 : LOCK lock() old = new q=q->next 2 LOCK [q!=NULL] 3 LOCK q->data = new unlock() new++ 4 : LOCK [new==old] 5 : LOCK 5 unlock() 4 : LOCK 1 2 3 Reachability Tree Predicates:LOCK
Analyze Counterexample Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); } 1 : LOCK old = new 2 LOCK 3 LOCK new++ 4 : LOCK [new==old] 5 : LOCK 5 Inconsistent 4 : LOCK new == old 1 2 3 Reachability Tree Predicates:LOCK
Repeat Build-and-Search Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); } 1 : LOCK 1 Reachability Tree Predicates:LOCK, new==old
Repeat Build-and-Search Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); } 1 : LOCK lock() old = new q=q->next 2 LOCK , new==old 1 2 Reachability Tree Predicates:LOCK, new==old
Repeat Build-and-Search Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); } 1 : LOCK 2 LOCK , new==old 3 LOCK , new==old q->data = new unlock() new++ 4 : LOCK , : new = old 4 1 2 3 Reachability Tree Predicates:LOCK, new==old
Repeat Build-and-Search Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); } 1 : LOCK 2 LOCK , new==old 3 LOCK , new==old 4 : LOCK , : new = old [new==old] 4 1 2 3 Reachability Tree Predicates:LOCK, new==old
Repeat Build-and-Search Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); } 1 : LOCK 2 LOCK , new==old 3 LOCK , new==old 4 : LOCK , : new = old [new!=old] 1 : LOCK, : new == old 4 4 1 2 3 Reachability Tree Predicates:LOCK, new==old
Repeat Build-and-Search Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); } 1 : LOCK 2 LOCK , new==old SAFE 3 LOCK , new==old 4 4 LOCK , new=old : LOCK , : new = old 1 5 5 : LOCK, : new == old 4 4 4 1 : LOCK , new==old 2 3 Reachability Tree Predicates:LOCK, new==old
BLAST [HenzingerJhalaM.Sutre02] Yes Safe Abstract CProgram Refine No Property Trace
Scaling BLAST Yes Safe Abstract CProgram Refine No Property Trace Key Problem: Find good predicates To find:1.Which predicates to track? 2.Where to track them?
#Predicates grows with program size while(1){ 1: if (p1) lock() ; if (p1) unlock() ; … 2: if (p2) lock() ; if (p2) unlock() ; … n: if (pn) lock() ; if (pn) unlock() ; } T F T Tracking lock not enough Problem: p1,…,pn needed for verification Exponential reachable abstract states
#Predicates grows with program size while(1){ 1: if (p1) lock() ; if (p1) unlock() ; … 2: if (p2) lock() ; if (p2) unlock() ; … n: if (pn) lock() ; if (pn) unlock() ; } : LOCK LOCK, p1 : LOCK, : p1 : LOCK, : p1 : LOCK, p1 : LOCK p1p2 p1: p2 : p1 p2 : p1: p2 2nAbstract States Problem: p1,…,pn needed for verification Exponential reachable abstract states
LOCK , p2 : LOCK , : p2 : LOCK Predicates useful locally while(1){ 1: if (p1) lock() ; if (p1) unlock() ; … 2: if (p2) lock() ; if (p2) unlock() ; … n: if (pn) lock() ; if (pn) unlock() ; } : LOCK p1 LOCK , p1 : LOCK, : p1 : LOCK , : p1 : LOCK : LOCK , p1 : LOCK : LOCK p2 pn 2n Abstract States Solution: Use predicates only where needed
Main Questions Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); } 1 : LOCK Q. How to find good predicates ? Where to track each predicate? 2 LOCK , new==old SAFE 3 LOCK , new==old 4 4 LOCK , new=old : LOCK , : new = old 1 5 5 Refinement : LOCK, : new == old 4 4 4 1 : LOCK , new==old 2 3 Predicates:LOCK, new==old
Counterexample Traces lock1= 1 old1 = new0 q1 = q0->next assume(q1 != NULL) (q1 ->data)1 = new0 lock2 = 0 new1 = new0 +1 assume(new1=old1) assert(lock2=1) lock1= 1 Æ old1 = new0Æ q1 = q0->next Æ q1 != NULL Æ (q1 ->data)1 = new0 Æ lock2 = 0 Æ new1 = new0 +1 Æ new1=old1 lock() old = new q=q->next [q!=NULL] q->data = new unlock() new++ [new==old] unlock() Trace Feasibility Formula Trace SSA Trace Thm: Trace is feasible, TF is satisfiable
Proof of Unsatisfiability lock1= 1 Æ old1 = new0Æ q1 = q0->next Æ q1 != NULL Æ (q1 ->data)1 = new0 Æ lock2 = 0 Æ new1 = new0 +1 Æ new1=old1 old1= new0 new1= new0 + 1 new1 = old1 new1= old1+1 ; Proof of Unsatisfiability Predicates: old=new, new=new+1, new=old Trace Feasibility Formula Add: old=new [HenzingerJhalaM.Sutre02]
Decision Procedure Must Produce Proofs Sat asgn Decision Procedure yes Proof no Boolean SAT Proofs important in other applications as well: e.g., Proof carrying code [Necula97,HenzingerJhalaM.NeculaSutreWeimer02]