Presentation is loading. Please wait.

Presentation is loading. Please wait.

Deductive Verification Tools Tutorial for Dagstuhl Seminar 16201

Similar presentations


Presentation on theme: "Deductive Verification Tools Tutorial for Dagstuhl Seminar 16201"— Presentation transcript:

1 Deductive Verification Tools Tutorial for Dagstuhl Seminar 16201
while(i>0) { i--; } ………… ………… ………… Note: slide numbers 18th May 2016 Alexander J. Summers ETH Zurich, Switzerland

2 Deductive Verification Tools
while(i>0) { i--; } Take a program

3 Deductive Verification Tools
while(i>0) { i--; } ………… ………… ………… spec Take a program annotated with some specifications Automate a reasoning technique to find proof / errors typically: consider each program point only once This part of the tutorial: example deductive verification tools and their use how to construct new ones Not here: static analysers, proof assistants, …

4 Deductive Verification Tools
full software stack for secure remote apps safety, liveness, functionality of distributed systems Java concurrency, GPU software, kernel code Ironclad IronFleet VerCors VCC Chalice VeriFast C and Java code (e.g. Linux device driver, Java Card) C code (e.g. MS Hypervisor) Race-free OO concurrency features (PL) Viper Intermediate Verification Language (more later…)

5 Concurrency Reasoning Ingredients
Ironclad IronFleet VerCors VCC Chalice VeriFast Invariants (per object / thread) Two-state (transition) invariants count <= old(count) Methodology for local verification Ownership as auxiliary state Other reasoning encodable e.g. claims for shared access Viper

6 Concurrency Reasoning Ingredients
Ironclad IronFleet VerCors VCC Chalice VeriFast Separation logic (for ownership) x.count ↦ 4 Reasoning Libraries (e.g. monitors) Shared Boxes with invariants (rely-guarantee reasoning) Lemma function pointers (ghost state maintenance) Viper

7 Concurrency Reasoning Ingredients
Ironclad IronFleet VerCors VCC Chalice VeriFast Access permissions (ownership) acc(x.count) Fractional permissions (sharing) Modular lock ordering specification (deadlock avoidance) Two-state monitor/lock invariants (CSL, plus some rely-guarantee) Viper

8 Demo (Owicki-Gries in Chalice)
class OwickiGries { requires rd(mu) && waitlevel << mu // may acquire lock var count: int ghost var g0: int requires (b ? acc(this.g0,50) : acc(this.g1,50)) ghost var g1: int ensures b ==> acc(this.g0,50) && this.g0 == old(this.g0) + 1 invariant acc(this.count) && acc(this.g0,50) ensures !b ==> acc(this.g1,50) && this.g1 == old(this.g1) + 1 && acc(this.g1,50) && this.count == this.g0 + this.g1 ensures rd(mu) { method Main() { acquire(this) var og := new OwickiGries{ count := 0, g0 :=0, g1 := 0 } this.count := this.count + 1 if(b) { share og // monitor available this.g0 := this.g0 + 1 } else { fork tk0 := og.Worker(false) this.g1 := this.g1 + 1 fork tk1 := og.Worker(true) join tk0; join tk1 release(this) acquire og; unshare og assert og.count == 2 } method Worker(b: bool)

9 Tool Design We did not develop a step-by-step proof
provide only the essence of the formal argument What is this essence? which assertions are essential information? modularity? to abstract control flow? which proof steps user directed (not syntactically)? which reasoning ingredients are natively supported? How can these ingredients be implemented? Option 1: implement custom support (hard) Option 2: design an encoding using an existing tool often: find a different way to model same idea Only sound if x.next will not be modified in future

10 Example: modelling ownership transfer
Partial heaps 4 inv 3 count 1 acquire (this) // Inhale the monitor invariant count := count + 1

11 Example: modelling ownership transfer
Partial heaps 4 inv 3 count 2 acquire (this) // Inhale the monitor invariant count := count + 1 release(this) // Exhale the monitor invariant

12 Example: modelling ownership transfer
Partial heaps Total heaps + accounting 3 4 4 inv inv 3 count 3 count 1 1 2 4 7 acquire (this) // Inhale the monitor invariant count := count + 1 release(this) // Exhale the monitor invariant

13 Example: modelling ownership transfer
Partial heaps Total heaps + accounting 3 4 4 inv inv 3 count 3 count 2 2 2 4 7 acquire (this) // Inhale the monitor invariant count := count + 1 release(this) // Exhale the monitor invariant

14 Implementing the reasoning
Partial heaps Total heaps + accounting 3 4 4 inv inv 3 count 3 count 2 2 2 4 7 maintain “heap chunks” in tool Add/remove for inhale/exhale Abstract over concrete values Value reasoning via SMT solver Symbolic execution (e.g. VeriFast) generate instrumented program track permissions as auxiliary state keep some heap values consistent Encode resulting program (Boogie) Embed proof obligations (e.g. Chalice)

15 Building up tool stacks…
Ironclad IronFleet VerCors VCC Chalice VeriFast Dafny Viper Encoding to express sufficient proof obligations (somehow) Encoding need not preserve operational semantics May involve auxiliary state, indirect modelling of features (Very) useful: support for desired reasoning ingredients Boogie Z3

16 Example: modelling ownership transfer
Partial heaps Total heaps + accounting 3 4 4 inv inv 3 count 3 count 2 2 2 4 7 acquire (this) // Inhale the monitor invariant count := count + 1 release(this) // Exhale the monitor invariant // inhale / gain ownership assert Mask[this,count] == 1 Heap[this,count]++ Mask[this.count]-- // exhale / release ownership

17 Demo 2 (encoding Chalice in Viper)
class OwickiGries { var count: int ghost var g0: int ghost var g1: int invariant acc(this.count) && acc(this.g0,50) && acc(this.g1,50) && this.count == this.g0 + this.g1 method Main() { var og := new OwickiGries{ count := 0, g0 :=0, g1 := 0 } share og // monitor available fork tk0 := og.Worker(false) fork tk1 := og.Worker(true) join tk0; join tk1 acquire og; unshare og assert og.count == 2 } method Worker(b: bool) requires rd(mu) && waitlevel << mu // may acquire lock requires (b ? acc(this.g0,50) : acc(this.g1,50)) ensures b ==> acc(this.g0,50) && this.g0 == old(this.g0) + 1 ensures !b ==> acc(this.g1,50) && this.g1 == old(this.g1) + 1 ensures rd(mu) { acquire(this) this.count := this.count + 1 if(b) { this.g0 := this.g0 + 1 } else { this.g1 := this.g1 + 1 release(this) field count: Int field g0: Int field g1: Int // monitor invariant define inv (acc(og.count) && acc(og.g0,1/2) && acc(og.g1,1/2) && og.count == og.g0 + og.g1) method Main() { var og : Ref; og := new(count,g0,g1); // specify the fields which the object has og.count := 0; og.g0 := 0; og.g1 := 0; // share monitor: exhale invariant exhale inv // fork first thread := Worker(og,true) (uses g0 ghost variable) label l0 exhale acc(og.g0,1/2) // fork second thread := Worker(og,false) (uses g1 ghost variable) label l1 exhale acc(og.g1,1/2) // join thread 0 (Worker(og,true)) inhale acc(og.g0,1/2) && og.g0 == old[l0](og.g0) + 1 // join thread 1 (Worker(og,false)) inhale acc(og.g1,1/2) && og.g1 == old[l1](og.g1) + 1 // acquire the monitor (for remaining permissions) - can be unshared in source program inhale inv assert og.count == 2 } method Worker(og:Ref, b:Bool) // mu-related deadlock checking: omitted requires (b ? acc(og.g0,1/2) : acc(og.g1,1/2)) ensures (b ==> acc(og.g0,1/2) && og.g0 == old(og.g0) + 1) ensures (!b ==> acc(og.g1,1/2) && og.g1 == old(og.g1) + 1) { og.count := og.count + 1 if(b) { og.g0 := og.g0 + 1 } else { og.g1 := og.g1 + 1

18 The Viper Project Viper IVL
We have designed a new intermediate verification language Reusable, native support for various common reasoning ingredients e.g. permissions, inhale/exhale Idea: front-end tools that encode a problem into a Viper program We provide (two) Viper Verifiers In use for several projects (later): Developing full-blown verifiers Hand-coding examples Building prototypes quickly Program + properties Viper IVL Viper Verifiers Automatic Provers etc.

19 Viper: a toolbox for concurrency verification
Object-based (but not OO – no classes/inheritance) Declarations: fields, methods, predicates, functions Statements: assignments, loops, calls, inhale/exhale loops have invariants, methods have pre/post specs Assertion language: permissions, rich functional specs user-defined predicates (implemented or abstract) mathematical (heap-dependent) pure functions Very simple type system four basic types: Int, Bool, Perm, Ref (all references) sequence and set types: Seq[T], Set[T] (+ operations) Domains allow user to specify custom types via extra domain functions and quantified axioms e.g. tuples, maps, arrays…

20 Demo (encoding RSL) field val : Int // integer pointer value predicate R(x: Ref) predicate W(x: Ref) field alreadyRead : Set[Int] // for updating invariant // x.store(i,release) define RELEASE(i,x) { if(i!=0) { exhale acc(a.val) && a.val == 7 } method unknownInt() returns (x:Int) // t := x.load(acq) define ACQUIRE(t,x) { t := unknownInt() if(t==0 || t in x.alreadyRead) { // do nothing } else { inhale acc(a.val) && a.val == 7 // a.val pointsto 7 x.alreadyRead := x.alreadyRead union Set(t) define leftPre (acc(a.val) && a.val == 0 && acc(W(x))) define leftPost true define rightPre acc(R(x)) && acc(x.alreadyRead) && x.alreadyRead == Set[Int]() define rightPost true method outerScope() { var a: Ref var x: Ref x := new(); // atomic RELEASE(0,x); inhale acc(R(x)) && acc(W(x)) && acc(x.alreadyRead) && x.alreadyRead == Set[Int]() a := new(); // non-atomic inhale acc(a.val) a.val := 0 // fork both threads exhale leftPre exhale rightPre // join both threads inhale leftPost inhale rightPost method leftThread(a:Ref, x:Ref) requires leftPre ensures leftPost { a.val := 7 assert acc(W(x)) RELEASE(1,x) method rightThread(a:Ref, x:Ref) requires rightPre ensures rightPost var t : Int assert acc(R(x)) ACQUIRE(t,x) if (t != 0) { assert a.val == 7

21 Some Viper Applications
Python ….. Java (VerCors) Chalice OpenCL (VerCors) Viper Tools released 1.5 years ago open-source, publicly available in use both at ETH and outside Chalice: re-implementation concurrency verification Scala (small fragment) Finite blocking verification VerCors (ERC) project Marieke Huisman (UTwente) Java, GPU code, kernel code SCION router code (Python) Adrian Perrig (ETH Zurich) (coming soon) JavaScript (Philippa Gardner) Fine-grained concurrency logics [Your tool name here? ]

22 Conclusion: Deductive Verification Tools
while(i>0) { i--; } ………… ………… ………… spec Provide powerful reasoning abstractions for direct users, but also for other tool developers to plug into Divide a concurrency verification task between: expressing appropriate specifications per program encoding (in a tool) of a concurrency reasoning technique leveraging intermediate tools and reasoning abstractions ultimately exploiting SMT solvers (+ other automatic tools?)


Download ppt "Deductive Verification Tools Tutorial for Dagstuhl Seminar 16201"

Similar presentations


Ads by Google