810 likes | 961 Vues
This paper presents a novel approach to predicate abstraction tailored for shared-variable concurrent programs. By incorporating symmetry awareness, it addresses the state explosion problem often encountered in concurrent software analysis. This method generates Boolean programs that facilitate the application of finite-state model checkers, enabling effective analysis of mainstream programming languages. The authors provide an overview of predicate abstraction, its applications, and experimental results demonstrating the efficacy of their approach. The findings are crucial for improving reliability in concurrent system development.
E N D
Symmetry-Aware Predicate Abstraction for Shared-Variable Concurrent Programs Alastair Donaldson, Alexander Kaiser, Daniel Kroening, and Thomas Wahl Computer Science Department, Oxford University, United Kingdom Limor Goldberg 15.4.2012
Outline • Introduction • Symmetry-Aware Predicate Abstraction • Symmetry-Aware Predicate Abstraction with aliasing • Closing the CEGAR Loop • Experimental results • Conclusion
Introduction • Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution
Overview • Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution • Enables applying finite- state model checkers to programs written in mainstream languages • The use of predicate abstraction till now Goal: present an application of PA to shared variable concurrent software
Overview • Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution A symmetry aware predicate abstraction: • Consider the replicated structure of a C program consists of many threads • Generate a boolean program
Predicate Abstraction • Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution Predicate: A first order atomic formula over variables V Examples: x+y<z2, x=5 Let Þ be a program and let φ be an ACTL* formula, AP = {P1,….,Pk} ,includes: • Atoms(φ), the set of predicates appearing in φ • Some of the conditions in control statements in
Predicate Abstraction • Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution The abstractstates: {B1,…,Bk} when each predicate Pj is associated with a boolean variable Bj The Abstraction mapping h: h(s)=
Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution Predicate Abstraction States label: • A concrete state labeled with all the predicates it satisfied. • An abstract states labeled with predicate the corresponding bit is 1 in that state. Example:
Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution Example • let be a program with variable x,y and a single transition x:=x+1. • AP={P1,P2,P3} where: • P1 = ( x1 ) • P2= ( x>y ) • P3 = ( y=2 ) Some of the labels are: • L((0,0))=L((1,1)) = L((0,1)) ={P1} • L((0,2))= L((1,2)) = {P1, P3} • L((2,0))={P2}
Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution Example • let be a program with variable x,y and a single transition x:=x+1. • AP={P1,P2,P3} where: P1 = ( x1 ) , P2= ( x>y ) , P3 = ( y=2 ) • S = {s, t} • s(x) = s(y) = 0 • t(x) = 1, t(y) = 2 • L(s) = {P1} , L(t) = {P1, P3}
Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution Example • let be a program with variable x,y and a single transition x:=x+1. • AP={P1,P2,P3} where: P1 = ( x1 ) , P2= ( x>y ) , P3 = ( y=2 ) • {0,1}3 . • We define the abstraction mapping h: • h((0,0))= h((1,1)) = h((0,1)) =(1,0,0) • h((0,2))= h((1,2)) =(1,0,1) • h((2,0))= {P2} = (0,1,0)
Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution Example • let be a program with variable x,y and a single transition x:=x+1. • AP={P1,P2,P3} where: P1 = ( x1 ) , P2= ( x>y ) , P3 = ( y=2 ) • S = {s, t} : s(x) = s(y) = 0 , t(x) = 1, t(y) = 2 • L(s) = {P1} , L(t) = {P1, P3} • the abstraction mapping h: • h(s) = (1,0,0), h(t) = (1,0,1). • () = (1,0,0) = L(s) = {P1} • ( ) = (1,0,1) = L(t) = {P1, P3}
Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution Example • Example: • For (1,0,0) and (0,1,0) : • They are in iff exist x,y,x’,y’ which satisfied the formula above. • We can see that (1,1) and (2,1) provide all we need (1,1) (1,0,0) (2,1) (0,1,0)
Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution Uses of predicate abstraction • Predicate abstraction introduces as a way of dealing with data state explosion • It turns C programs into finite state boolean programs which can be model checked • Analyzing sequential software: • In the SLAM project at Microsoft, using this approach, was able to discover numerous control-dominated errors in low level operating system code.
Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution Uses of predicate abstraction • The bottleneck of PA in shared variable concurrent programs: • the exponential dependence of the generate state apace on the number of running threads. • Solution – exploit symmetry
Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution Uses of predicate abstraction • Our goal is a scheme that: • Translate a non-recursive C program with global scope and procedure scope into a Boolean program • The n-thread Boolean program (n), shell soundly overapproximates the n-thread C program (n) • Such an abstraction method called – symmetry aware • Permits predicates over arbitrary C programs variables, local or global.
Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution Uses of predicate abstraction • We present program as code fragments that declare shred and local variables. • such code is to be understood as a procedure to be executed by any number of threads • The code can declare shared variables – declared at the global scope (the complete program) • Can declare local variables (within the procedure)
Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution Naïve solution • Since the program B is executed by parallel threads its variables have to be partitioned into “shared” and “local” . • The “shared” and “local” attribute of B’s variables depend on the attributes of P’s variables a predicate is formulated over. • Definition: • A local predicate refers solely to a local C program variables • A shared predicate refers solely to a shared C program variables • A mixed predicate is neither local nor shared.
Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution Naïve solution • Definition: • A local predicate refers solely to a local C program variables • A shared predicate refers solely to a shared C program variables • A mixed predicate is neither local nor shared. Example to mix predicate: let s and l be a shared and local variables respectively. b is a boolean corresponding to the predicate: s != l Thus b is a mix variable
Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution Naïve solution The decision whether a mix predicate should be track in the shared or local space in the Boolean program is non-obvious. Example: local variable b track the mix predicate s != l : : shared int s = 0; local intl = 1; assert s != l; ++s; local bool b = 1; assert b; b = b ? * : 1 ;
Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution Naïve solution shared int s = 0; local intl = 1; assert s != l; ++s; local bool b = 1; assert b; b = b ? * : 1 ; : : What’s the problem? Consider the program 2 : we can see that execute this program can lead to an assertion violation. But, the corresponding concurrent Boolean program 2is correct. 2 is an unsound abstraction for 2
Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution Naïve solution So, we’ll try to track a mix predicate with a shared Boolean variable: Example: shared variable b tracks the mix predicate s == l : : shared int s = 0; shared bool t = 0; local int l = 0; If * then if t then assert s != l; l = s + 1; t = 1; shared bool b = 1; shared bool t = 0; If * then if t then assert ! b; b = 0; t = 1;
Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution Naïve solution shared int s = 0; shared bool t = 0; local int l = 0; If * then if t then assert s != l; l = s + 1; t = 1; shared bool b = 1; shared bool t = 0; If * then if t then assert ! b; b = 0; t = 1; : : Still, we have the same problem! 2 is an unsound abstraction for ’2
Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution Naïve solution The unsoundness can be eliminated by making b local in . But, an analogous reasoning removes the unsoundness in as abstraction to . Conclusion: a predicate of the form s == l that genuinely depends on s and l cannot be tracked by a shared or a local variable
Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution Naïve solution • The assertion in this program cannotcannot be violated • We can prove that over a set od nonmixed predicates, no invariant is computable that is strong enoughto prove s == l. 0: shared int s = 0; 1: shared intr= 0; 2: local int l = 0; 3: ++r; 4: if ( r == 1 ) then 5: ++s; ++l; 6: assert s == l; 7: goto 5
Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution Naïve solution Solution: • Instantiate the template n times into programs {1, . . ., n} • Every predicate refers to local variables instantiated n times
Overview • Predicate Abstraction • Example • Uses of predicate abstraction • Naïve solution Naïve solution - summarize • Mixed predicate as local • Make unsound abstraction • Mixed predicate as shared • Make unsound abstraction • Use only shared or local predicate • Cannot verify a simple bug-free program • Instantiate the template as the number of threads • The program is no longer symmetric – cause state explosion • Symmetry oblivious – will not scale beyond a very small number of threads
Symmetry Aware Predicate Abstraction • Definitions • Mixed predicate and notify all updates • Implementing Notify-All updates • The predicate abstraction algorithm
Definitions • Definitions • Mixed predicate • Notify All implementation • The algorithm • VS : a set of shared variables • VL: a set of local variables • Loc() = {v: v occurs in } • affects(v,) = variable v affects • must_notify(v,) = the shared variable v affects the mixed predicate • A predicate i is : • shared iffLoc(i)VS • local iffLoc(i)VL • mixed iffLoc(i)VSand Loc(i)VL
Definitions • Mixed predicate • Notify All implementation • The algorithm Let be a program defined over a set of variables V = VS VL The parallel execution of by n threads is a program defined over VS and n copies of VL . • No aliasing • Assignment to v cannot modify another variable but v • An expression depends only on the variables occurring in it
Mix predicates and Notify-All updates • Definitions • Mixed predicate • Notify All implementation • The algorithm Let E = {1, … ,m} be a set of predicates over . {b1, … , bm} is the Boolean variables in program . bi tracks over predicate i . We partition the boolean variables: bi is shared if iis shared. otherwise, bi is local.
Mix predicates and Notify-All updates • Definitions • Mixed predicate • Notify All implementation • The algorithm We have noticed that mixed predicate are tracked in local variables Why? Declaring bi shared would lose information, declaring it local doesn’t – though, it is insufficient to guarantee a sound abstraction. This is a problem we can solve!
Mix predicates and Notify-All updates • Definitions • Mixed predicate • Notify All implementation • The algorithm • Each statement in is translated into a corresponding statement in • Handling assignments: consider an assignment to variable v in and a Boolean variable b of with associated predicate : • First we check affects (v, ) • if it evaluates to false – b does not change • otherwise, code needs to be generated to update b.
Mix predicates and Notify-All updates • Definitions • Mixed predicate • Notify All implementation • The algorithm We need to consider three different update of b: • Shared update -v and are both shared : we generate code to update b according to the (*)standard sequential predicate abstraction rule.
Mix predicates and Notify-All updates • Definitions • Mixed predicate • Notify All implementation • The algorithm • Local update -v is local and is local or mixed: the value of b changes only for the active thread.
Mix predicates and Notify-All updates • Definitions • Mixed predicate • Notify All implementation • The algorithm • Notify-All update -v is shared and is mixed: the mixed predicate is tracked by local variable b. • We generate code to update b locally (like in previous cases) • We notify all passive threads about the modification of shared variable v (and they will update their local copy of b) this formula evaluates to true exactly when its necessary to notify passive threads of an update to v
Weakest precondition • Definitions • Mixed predicate • Notify All implementation • The algorithm For a statement st and a predicate WP(st , ) is the weakest predicate whose truth before s entails the truth of after st terminates. For example: WP (x=x+1 , x<5) = (x<4)
Weakest precondition • Definitions • Mixed predicate • Notify All implementation • The algorithm Statement st occurs between program points p and p’. is a predicate in E with corresponding boolean b. it is safe to assign b:=true between p and p’ if the boolean variable , b’ , corresponding to WP(st, ) is true at point p. But , what happened if WP(st, ) isn’t in E ?
Weakest precondition • Definitions • Mixed predicate • Notify All implementation • The algorithm Example: E = {(x<5) , (x=2) } we have seen that WP(x=x+1,x<5) = x<4 but x<4 is not in E. In that case we need to strengthen the WP to an expression over the predicated in E. (x = 2) (x<4) if (x=2) is true before x:=x+1, then x<5 is true afterwards
Weakest precondition • Definitions • Mixed predicate • Notify All implementation • The algorithm Example: E = {(x<5) , (x=2) } we have seen that WP(x=x+1,x<5) = x<4 but x<4 is not in E. In that case we need to strengthen the WP to an expression over the predicated in E. (x = 2) (x<4) if (x=2) is true before x:=x+1, then x<5 is true afterwards (WP(st, )) the strengthens of WP.
Weakest precondition • Definitions • Mixed predicate • Notify All implementation • The algorithm (*)sequential predicate abstraction: Given a set E = {1, … ,m} of predicates tracked by variable {b1, … , bm} , assignment statement stis translated into the following code, for each i {1,…,m}: if (WP(st, i)) then bi = 1 else if (WP(st,i)) then bi = 0 else bi= *
Weakest precondition • Definitions • Mixed predicate • Notify All implementation • The algorithm For example: : (l<10) tracked by b, E={} , st: (++l) ( WP(st, ) ) = ( l < 9 ) = false ( WP(st, ) ) = ( l 9) = l 10 = So, according to the previous formula: b = ( b ? * : 0 )
Weakest precondition • Definitions • Mixed predicate • Notify All implementation • The algorithm In general, the formula is often abbreviated using the assignment: bi = choose (( WP(st, i) ) , ( WP(st, i) ) ) Where choose (x,y) return 1 if x evaluates to true, 0 if x y evaluates to true * otherwise
Implementing Notify-All updates • Definitions • Mixed predicate • Notify All implementation • The algorithm If must_notify( v, ) evaluated to true tracked in by a local boolean , b. Predicate abstracting an assignment of the form v = is implemented using two assignments. (1) b = choose (( WP(st, ) ) , ( WP(st, ) ) ) (2) [b] = choose (( WP(st, []) ) , ( WP(st, ]) ) )
Implementing Notify-All updates • Definitions • Mixed predicate • Notify All implementation • The algorithm [b] stands for the copy of local variable b owned by some passive thread Similarly, [] stands for the expression defining predicate , but with every local variable occurring in the expression replaced by the copy owned by the passive thread
Implementing Notify-All updates • Definitions • Mixed predicate • Notify All implementation • The algorithm (1) b = choose (( WP(st, ) ) , ( WP(st, ) ) ) (2) [b] = choose (( WP(st, []) ) , ( WP(st, ]) ) ) Example: Statement: (s = l) shared and local variable Mixed predicate, : (s == l) The code generated for this is: b = true [b] = choose (( WP(s=l, s==[l]) ) , ( WP(s=l, (s==[l]) ) )) [b] = choose ((l==[l]) , ( WP(s=l, (l==[l]) ) ))
The Algorithm • Definitions • Mixed predicate • Notify All implementation • The algorithm
The Algorithm • Definitions • Mixed predicate • Notify All implementation • The algorithm Indexes of all the predicate that that effected by v