predicate abstraction for software verification cormac flanagan shaz qadeer compaq systems research...
Post on 21-Dec-2015
221 views
TRANSCRIPT
Predicate Abstraction for Software Verification
Cormac Flanagan
Shaz QadeerCompaq Systems Research Center
POPL02The Continuing Saga of Predicate Abstraction
Extended Static Checking
• Statically verify many correctness properties
• Type systems catch many errors
– e.g. “Cannot multiply a number and a string”• Would like to catch additional errors
– e.g. “Array index out of bounds at line 10”• And verify other correctness properties
– assertions– object invariants– lightweight method specifications
Checking loops with ESC/Java/*@ loop_invariant i >= 0; loop_invariant 0 <= spot; loop_invariant spot <= MAXDIRENTRY; loop_invariant (\forall int j; 0 <= j && j < i && bdisk[addr].dirEntries[j].inum != DIRENTRY_UNUSED ==>
bdisk[addr].dirEntries[j].name != name); loop_invariant (\forall int j; spot == MAXDIRENTRY && 0 <= j && j < i ==> bdisk[addr].dirEntries[j].inum != DIRENTRY_UNUSED);
loop_invariant spot == MAXDIRENTRY || bdisk[addr].dirEntries[spot].inum == DIRENTRY_UNUSED;
loop_invariant (\forall DirEntry t; t != de ==> t.name == \old(t.name)); loop_invariant (\forall DirEntry t; t != de ==> t.inum == \old(t.inum)); loop_invariant (\forall DirEntry t; t.inum == FS.DIRENTRY_UNUSED ||
(0 <= t.inum && t.inum < FS.IMAX));*/for (i = 0; i < cwd.inode.length; i++) { GetDirEntry(de, addr, i); if (de.inum != DIRENTRY_UNUSED && de.name == name) { return ERROR; } if (de.inum == DIRENTRY_UNUSED && spot == MAXDIRENTRY) { spot = i; }}
Loop invariants
C;
while e do B end
Set of reachable states at loop head is a loop invariant!
sp(C, p)p C
Concrete states
I0 I1 I2 In... ...
Abstract states
J0 J1 J2 Jn... ...
(Ik) = JkIk = (Jk)
Abstract interpretation
Cousot-Cousot 77
Predicate abstractionGraf-Saidi 97
Computing loop invariantsC;
while e do
X;
Y;
end
{ I0 = (sp(C, true)) }
{ J0 = ((I0) e) }
{ K0 = (sp(X, (J0))) }
{ L0 = (sp(Y, (K0))) }
Computing loop invariantsC;
while e do
X;
Y;
end
{ I1 = I0 L0 }
{ J1 = ((I1) e) }
{ K1 = (sp(X, (J1))) }
{ L1 = (sp(Y, (K1))) }
/*@ requires a!=null && b!=null && a.length==b.length ensures \result==a.length || b[\result] */int find(int[] a, boolean[] b) { int spot = a.length; for (int i=0; i < a.length; i++) { if (spot==a.length && a[i] != 0) spot = i; b[i] = (a[i] != 0); } return spot;}
Predicate abstraction example
Ten predicates:a != nullb != nulla.length == b.lengthspot == a.lengthb[spot]spot < i0 <= ii < a.lengthspot = ia[i] != 0
Computing loop invariantsC;
while e do
X;
Y;
end
{ I0 = (sp(C, true)) }
{ L0 = (sp(“X;Y”, (I0)e)) }
Computing loop invariantsC;
while e do
X;
Y;
end
{ I1 = I0 L0 }
{ L1 = (sp(“X;Y”, (I1)e)) }
/*@ requires a!=null && b!=null && a.length==b.length ensures \result==a.length || b[\result] */int find(int[] a, boolean[] b) { int spot = a.length; for (int i=0; i < a.length; i++) { if (spot==a.length && a[i] != 0) spot = i; b[i] = (a[i] != 0); } return spot;}
Predicate abstraction example
Seven predicates:a != nullb != nulla.length == b.lengthspot == a.lengthb[spot]spot < i0 <= ii < a.lengthspot = ia[i] != 0
Computing loop invariants
C;
while e do
X;
Y;
end
{ I0 = (sp(C, true)) }
H = havoc variables modified in X;Y
P0 = “C;H;assume (I0)e;X;Y”
{ L0 = (sp(P0, true)) }
Computing loop invariants
C;
while e do
X;
Y;
end
{ I1 = I0 L0 }
H = havoc variables modified in X;Y
P1 = “C;H;assume (I1)e;X;Y”
{ L1 = (sp(P1, true)) }
/*@ requires a!=null && b!=null && a.length==b.length ensures \result==a.length || b[\result] */int find(int[] a, boolean[] b) { int spot = a.length; for (int i=0; i < a.length; i++) { if (spot==a.length && a[i] != 0) spot = i; b[i] = (a[i] != 0); } return spot;}
Predicate abstraction example
Four predicates:a != nullb != nulla.length == b.lengthspot == a.lengthb[spot]spot < i0 <= ii < a.lengthspot = ia[i] != 0
/*@ requires a!=null && b!=null && a.length==b.length ensures ( int j; 0<=j && j<\result ==> !b[j]) */int find(int[] a, boolean[] b) { int spot = a.length; for (int i=0; i < a.length; i++) { if (spot==a.length && a[i] != 0) spot = i; b[i] = (a[i] != 0); } return spot;}
Predicate abstraction example
( int j; 0<=j && j<i && j<spot ==>!b[j])
Invariant needed:
First method:add predicate ( int j; 0<=j && j<i && j<spot ==> !b[j])
-quantified loop invariants
Better method:
add skolem constant int jadd predicates 0<=j, j<i, j<spot, !b[j]infer 0<=j && j<i && j<spot ==>!b[j] Magic: int j; 0<=j && j<i && j<spot ==>!b[j])
Heuristics for guessing predicates
for (int i = 0; i < a.length; i++) a[i] = null;
Loop targets: i, a[*]
First set of predicates: i <= \old(i), i >= \old(i)
skolem_constant int sc
Second set of predicates: 0 <= sc, sc < i, a[sc] != null
Inferred invariant:i >= 0 int sc; 0 <= sc sc < i a[sc] == null
Javafe
• front end to ESC/Java• annotated with lightweight specifications • 45KLOC, 2418 routines, 520 loops• no inference warnings in 326 routines• with inference warnings in 31 routines• several failing routines had array bound
violations – not caught with loop unrolling
Computing abstraction function
• Compute
– I0 = (sp(C, true))
– In+1 = In (sp(“C;H;assume (In)e;B”, true))
• Problem: Given F compute (F)
(F) = least boolean function G such that F (G)
C; {I?}while e do B end
Abstract state space• Predicates {a, b, c, d}• They generate an abstract space of size 24 = 16
F
ab
ab
ab
ab
cd
cd
cd
cd
State Space
(F)
Naïve method (slow!)• Is F a b c d satisfiable? No!
• Can compute (F) by asking 2n such queries
ab
ab
ab
ab
cd
cd
cd
cd
F
(F)X X X X
X
X
XX
X
X X
New method• F a b c d ? No!
ab
ab
ab
ab
cd
cd
cd
cd
F
(F)X X X X
X
X
XX
X
X X
• F a c d ? No!• F c d ? No! • Removed 1/4 of state space in 3 queries!
= (c d) (a c) (a b) ( c d)
Other methods
• Das-Dill-Park 99 (DDP)• Saidi-Shankar 99 (SS)
Experiments
Benchmark Number of predicates
FQ DDP SS
partition 4 27 28 41
sort(outer) 6 44 54 111
sort(inner) 7 37 32 40
find 8 111 110 129
create 15 358 1191 2012
0
100
200
300
400
500
600
700
800
900
1000
0 2 4 6 8 10 12 14 16Predicates per Loop
Queries
FQ
DDP
SS
Experiments (Javafe)
Related work• Inferring/computing loop invariants
– German-Wegbreit 75– Katz-Manna 76– Suzuki-Ishihata 77
• Predicate abstraction– Graf-Saidi 97– Bensalem-Lakhnech-Owre 98, Colon-Uribe 98– Saidi-Shankar 99, Das-Dill-Park 99– Ball-Majumdar-Millstein-Rajamani 2001– Henzinger-Jhala-Majumdar-Sutre 2002