V erification de programmes avec pointeurs ` a laide de r egions - - PowerPoint PPT Presentation

v erification de programmes avec pointeurs a l aide de r
SMART_READER_LITE
LIVE PREVIEW

V erification de programmes avec pointeurs ` a laide de r egions - - PowerPoint PPT Presentation

INRIA Saclay Universit e de Paris-Sud 11 Ile-de-France Centre dOrsay Equipe ProVal V erification de programmes avec pointeurs ` a laide de r egions et de permissions Romain Bardou pr esent ee le 14 octobre 2011


slide-1
SLIDE 1

Universit´ e de Paris-Sud 11 INRIA Saclay – ˆ Ile-de-France Centre d’Orsay Equipe ProVal

V´ erification de programmes avec pointeurs ` a l’aide de r´ egions et de permissions

Romain Bardou pr´ esent´ ee le 14 octobre 2011 devant le jury compos´ e de : MM. Peter M¨ uller Fran¸ cois Pottier Jean Goubault-Larrecq Burkhart Wolff Claude March´ e

1 / 51

slide-2
SLIDE 2

There are two ways to write error-free programs;

  • nly the third one works.

— Alan J. Perlis

2 / 51

slide-3
SLIDE 3

Program Verification

programming needs thinking verification is tedious human machine thinking good bad repetition bad good parts of verification are repetitive = ⇒ let the human program and the machine verify

Introduction Program Verification 3 / 51

slide-4
SLIDE 4

Trade-Off: Automation vs. Expressiveness

properties: “x is always an integer” automated (typing) “x is always an odd integer” requires reasoning (annotations) “for all i, a[i] is prime” requires more reasoning (proofs)

Introduction Program Verification 4 / 51

slide-5
SLIDE 5

Deductive Program Verification

program + specification verification conditions automatic theorem provers (Alt-Ergo, Simplify, Z3, CVC3, ...) proof assistants (Coq, Isabelle, ...)

Introduction Deductive Program Verification 5 / 51

slide-6
SLIDE 6

Deductive Program Verification

expressiveness:

◮ mainstream programming languages (C, Java...) ◮ (at least) first-order logic for specifications

automation:

◮ specification written by hand ◮ automatic provers for simple verification conditions ◮ proof assistants for difficult verification conditions

Introduction Deductive Program Verification 6 / 51

slide-7
SLIDE 7

Deductive Verification: Example

void max(int i, int j) /*@ ensures \result >= i && \result >= j */ { if (i > j) return i; else return j; } verification conditions: i > j ⇒ i ≥ i ∧ i ≥ j ¬(i > j) ⇒ j ≥ i ∧ j ≥ j

Introduction Deductive Program Verification 7 / 51

slide-8
SLIDE 8

Pointers

pointer = variable containing a location pointed value = value stored at location

loc 42 · · · · · · x loc

Introduction Pointers 8 / 51

slide-9
SLIDE 9

Pointer Aliasing

*p = 42; *q = 69; /*@ assert *p = 42; */ what if p = q? verification conditions?

Introduction Pointers 9 / 51

slide-10
SLIDE 10

Data Invariants: Examples

handy specification tool “this array is always sorted” “this tree is a search tree” “this tree is well-balanced” “rocket speed is always positive”

Introduction Data Invariants 10 / 51

slide-11
SLIDE 11

Related Work

  • wnership

◮ Data Groups [Leino 1998] ◮ Ownership Types [Clarke, Potter, Noble 1998] ◮ Spec# Methodology [Barnett et al. 2004] ◮ Universe Types [Dietl, Muller 2005] ◮ Considerate Reasoning [Summers, Drossopoulou 2010]

alias control

◮ Separation Logic [Reynolds 2002] ◮ Regional Logic [Banerjee, Naumann, Rosenberg 2008] ◮ (implicit) Dynamic Frames [Kassios 2006; Smans et al. 2009]

Regions, Permissions / Capabilities, Alias Types...

Introduction Contributions 11 / 51

slide-12
SLIDE 12

Main Contribution

A type system using regions and permissions to structure the heap in a modular fashion, control pointer aliasing and data invariants and produce proof obligations where pointers are separated. implemented as a tool called Capucine

Introduction Contributions 12 / 51

slide-13
SLIDE 13

Contents

Introduction The Capucine Language Classes Regions Permissions Operations Ownership Coherence Preservation Conclusion Computing Verification Conditions Conclusion

The Capucine Language 13 / 51

slide-14
SLIDE 14

Classes

class = record + invariant + owned regions class Pair { fst: int; snd: int; invariant fst < snd; }

The Capucine Language Classes 14 / 51

slide-15
SLIDE 15

Pointer Types and Regions

region = set of locations memory structured using regions the type of a pointer [ρ] gives its region ρ fun incrPair [r: Pair] (p: [r]): unit { p.fst ← p.fst + 1; p.snd ← p.snd + 1; }

The Capucine Language Regions 15 / 51

slide-16
SLIDE 16

Life Cycle of Pointers

◮ allocation ◮ initialization of fields ◮ verification of the invariant ◮ insertion into a data structure ◮ update + invariant preservation

permissions track the state of objects

The Capucine Language Permissions 16 / 51

slide-17
SLIDE 17

Permissions

permission = type-level information about a region permissions evolve during execution: statements consume and produce permissions permissions cannot be duplicated

The Capucine Language Permissions 17 / 51

slide-18
SLIDE 18

Allocation and Initialization

  • peration let region r: C

◮ produces r∅

  • peration let x = new C [ρ]

◮ consumes ρ∅ ◮ produces ρ◦{f1, · · ·, fk} and owned permissions

  • peration x.f ← e when x: [ρ]

◮ consumes ρ◦{g} ◮ produces ρ◦{g−f }

The Capucine Language Operations 18 / 51

slide-19
SLIDE 19

Allocation: Example

let region r: Pair; r∅ let p = new Pair [r]; r◦{fst, snd} p.fst ← 42; r◦{snd} p.snd ← 69; r◦

The Capucine Language Operations 19 / 51

slide-20
SLIDE 20

Permission Diagram (so far)

let region r ∅ new r ◦{· · ·} ← r ◦

The Capucine Language Operations 20 / 51

slide-21
SLIDE 21

Packing and Unpacking

if y: [ρ]

  • peration pack y

◮ consumes ρ◦ and owned permissions ◮ produces ρ× ◮ requires the invariant of y as a pre-condition

  • peration unpack y

◮ consumes ρ× ◮ produces ρ◦ and owned permissions

note: ρ◦ required to modify y.f = ⇒ if ρ× available, then the invariant of y holds

The Capucine Language Operations 21 / 51

slide-22
SLIDE 22

Example: Incrementing a Pair

fun incrPair [r: Pair] (p: [r]): unit consumes r× produces r× { unpack p; r◦ p.fst ← p.fst + 1; r◦ p.snd ← p.snd + 1; r◦ pack p; (* invariant must hold *) r× }

The Capucine Language Operations 22 / 51

slide-23
SLIDE 23

Permission Diagram (so far)

r × let region r ∅ new r ◦{· · ·} ← r ◦ pack unpack r ×

The Capucine Language Operations 23 / 51

slide-24
SLIDE 24

Adoption: From Singleton to Group

if x: [σ]

  • peration adopt x: σ as ρ

◮ consumes σ× and ρG ◮ produces ρG ◮ type of x becomes [ρ]

x is then both in σ and ρ region σ is disabled

The Capucine Language Operations 24 / 51

slide-25
SLIDE 25

Permission Diagram

r × ρG let region r ∅ new r ◦{· · ·} ← r ◦ pack unpack r × adopt ρG

The Capucine Language Operations 25 / 51

slide-26
SLIDE 26

Focus: From Group to Singleton

  • peration focus x: ρ as σ

when x: [ρ]

◮ consumes ρG and σ∅ ◮ produces σ −◦ ρ and σ× ◮ type of x becomes [σ]

x is then both in σ and ρ region ρ is temporarily disabled

  • peration unfocus x: σ as ρ

when x: [σ]

◮ consumes σ −◦ ρ and σ× ◮ produces ρG ◮ type of x becomes [ρ]

region ρ is re-enabled region σ is disabled

The Capucine Language Operations 26 / 51

slide-27
SLIDE 27

Aliased or Not Aliased?

p and q may be aliased: fun f [r: Pair] (p: [r], q: [r]): unit consumes rG produces rG p and q cannot be aliased: fun f [rp: Pair, rq: Pair] (p: [rp], q: [rq]): unit consumes rpG rqG produces rpG rqG

The Capucine Language Operations 27 / 51

slide-28
SLIDE 28

Ownership

locations may own regions class LongPairOwn { single r1: Long; single r2: Long; fst: [r1]; snd: [r2]; invariant fst.value < snd.value; } invariant can only mention owned objects (enforced by typing)

The Capucine Language Ownership 28 / 51

slide-29
SLIDE 29

Allocation With Ownership

let region r: LongPairOwn; r∅ let p = new LongPairOwn [r]; r◦{fst, snd} p.r1 ∅ p.r2 ∅ let fst = new Long [p.r1]; r◦{fst, snd} p.r1 ◦{value} p.r2 ∅ fst.value ← 42; r◦{fst, snd} p.r1 ◦ p.r2 ∅ pack fst; r◦{fst, snd} p.r1 × p.r2 ∅ let snd = new Long [p.r2]; r◦{fst, snd} p.r1 × p.r2 ◦{value} snd.value ← 69; r◦{fst, snd} p.r1 × p.r2 ◦ pack snd; r◦{fst, snd} p.r1 × p.r2 × p.fst ← fst; r◦{snd} p.r1 × p.r2 × p.snd ← snd; r◦ p.r1 × p.r2 × pack p; r×

The Capucine Language Ownership 29 / 51

slide-30
SLIDE 30

Ownership: Summary

allows invariants to depend on owned fields

◮ need to unpack p to modify p.fst.value

structures the heap using an ownership tree

The Capucine Language Ownership 30 / 51

slide-31
SLIDE 31

Heap Coherence

we define a memory model and semantics for Capucine we define coherence of a heap w.r.t. available permissions

◮ empty regions are empty ◮ singleton regions have exactly one location ◮ locations in closed regions verify their invariant ◮ ...

The Capucine Language Coherence Preservation 31 / 51

slide-32
SLIDE 32

Coherence Preservation

Theorem (Coherence Preservation) Coherence of the heap is preserved through execution of a well-typed program.

The Capucine Language Coherence Preservation 32 / 51

slide-33
SLIDE 33

Summary and Contributions

take the existing notion of regions and permissions

◮ control aliasing

my contributions

◮ use permissions to control invariants ◮ add ownership ◮ add region parameters to classes ◮ add region polymorphism ◮ use inference to guess some operations

◮ pack, unpack, adoption, focus, unfocus The Capucine Language Conclusion 33 / 51

slide-34
SLIDE 34

Contents

Introduction The Capucine Language Computing Verification Conditions Use Regions to Separate Pointers Prefix Trees Experiments Progress Conclusion Conclusion

Computing Verification Conditions 34 / 51

slide-35
SLIDE 35

The Why Intermediate Language

the Why Language

◮ ML-like programs (without higher order) ◮ first-order logic ◮ references, with no aliasing ◮ computes weakest-precondition

encode Capucine programs as Why programs

◮ challenge: encode memory model to support aliasing

Computing Verification Conditions Use Regions to Separate Pointers 35 / 51

slide-36
SLIDE 36

Computing Verification Conditions

encode locations using an abstract type type location encode each region using a map type heap (α) logic select (heap (α), location): α logic store (heap (α), location, α): heap (α) encode objets as records

◮ each field encoded as a field ◮ each owned region encoded as a field of type heap

Computing Verification Conditions Use Regions to Separate Pointers 36 / 51

slide-37
SLIDE 37

Example: Two Regions (Capucine)

class Long = { value: int } fun incr2 [r1: Long, r2: Long] (i: [r1], j: [r2]) consumes r1 ◦ r2 ◦ produces r1 ◦ r2 ◦ post i.value = old(i.value) + 1 { i.value ← i.value + 1; j.value ← j.value + 1; }

Computing Verification Conditions Use Regions to Separate Pointers 37 / 51

slide-38
SLIDE 38

Example: Two Regions (Why)

type Long = { value: int } let incr2 (r1: ref (heap (Long)), r2: ref (heap (Long)), i: location, j: location) { true } r1 := store (!r1, i, { value = select (!r1, i).value + 1 }); r2 := store (!r2, j, { value = select (!r2, j).value + 1 }); { select (!r1, i).value = select (old(!r1), i).value + 1 }

Computing Verification Conditions Use Regions to Separate Pointers 38 / 51

slide-39
SLIDE 39

Issue

current translation: pros

◮ modify region =

⇒ other regions untouched current translation: cons

◮ modify owned region =

⇒ modify root region

Computing Verification Conditions Prefix Trees 39 / 51

slide-40
SLIDE 40

Flatten Ownership Tree

Burstall-Bornat component-as-array model

◮ one heap per field

idea: extend it to ownership trees

Computing Verification Conditions Prefix Trees 40 / 51

slide-41
SLIDE 41

Flatten Ownership Tree

type Long = { value: int } type LongPairOwn = { r1: heap (Long); r2: heap (Long); fst: location; snd: location } r: ref (heap (LongPairOwn)) becomes r r1 value: ref (heap (heap (int))) r r2 value: ref (heap (heap (int))) r fst: ref (heap (location)) r snd: ref (heap (location))

Computing Verification Conditions Prefix Trees 41 / 51

slide-42
SLIDE 42

Simplify Singleton Regions

r1 and r2 are singleton r r1 value: ref (heap (heap (int))) r r2 value: ref (heap (heap (int))) becomes r r1 value: ref (heap (int)) r r2 value: ref (heap (int))

Computing Verification Conditions Prefix Trees 42 / 51

slide-43
SLIDE 43

Flatten Ownership Tree

p.fst.value ← 42 without flattening: r := store (!r, p, { select (!r, p) with r1 = store (select (!r, p).r1, select (!r, p).fst, { select (select (!r, p).r1, select (!r, p).fst) with value = 42 }) }) with flattening and singleton simplification: r r1 value := store(!r r1 value, p, 42)

Computing Verification Conditions Prefix Trees 43 / 51

slide-44
SLIDE 44

Flattening: Issue

big data structures = ⇒ huge number of leaves in ownership tree = ⇒ huge number of references recursive data structures = ⇒ infinite number of references

Computing Verification Conditions Prefix Trees 44 / 51

slide-45
SLIDE 45

Prefix Tree

idea: only flatten what is used locally fun incrLeft [r: LongPairOwn] (p: [r]): unit { let x = p.left; x.value ← 42; }

r left right value value

node r is flattened = ⇒ references r left and r right node r left is flattened = ⇒ reference r left value

Computing Verification Conditions Prefix Trees 45 / 51

slide-46
SLIDE 46

Experiments

Alt-Ergo (10s timeout) without flattening with flattening Course 14s + 1 timeout 1.2s + 1 timeout Sparse Arrays (*) 120s 26s Z3 (10s timeout) without flattening with flattening Course 2s + 7 timeouts 1s + 3 timeouts Sparse Arrays (*) 96s + 10 timeouts 23s + 3 timeouts * Sparse Arrays = part of VACID-0 challenge [Leino 2010] (involves invariants and complex data structures)

Computing Verification Conditions Experiments 46 / 51

slide-47
SLIDE 47

Progress

Theorem (Progress) Assume a well-typed Capucine program, whose proof obligations have been proven. The program executes with no error. In particular, it verifies its specification.

Computing Verification Conditions Progress 47 / 51

slide-48
SLIDE 48

Summary and Contributions

previous work: use regions to separate pointers

◮ one map per group region ◮ one (location, value) pair per singleton region

my contributions

◮ apply this method with:

◮ allocation ◮ polymorphism ◮ ownership

◮ use prefix trees to achieve more separation

◮ experiments show this greatly helps automatic provers Computing Verification Conditions Conclusion 48 / 51

slide-49
SLIDE 49

Contents

Introduction The Capucine Language Computing Verification Conditions Conclusion

Conclusion 49 / 51

slide-50
SLIDE 50

Expressiveness vs. Automation

where does Capucine stand?

◮ region annotations in function prototypes ◮ no proof obligations for invariants except when packing ◮ inference of some pack, unpack, adopt, focus, unfocus ◮ type information can be used in hypotheses

(invariants, region of pointers, freshness)

Conclusion 50 / 51

slide-51
SLIDE 51

Future Work

from mainstream languages to Capucine

◮ annotation language? ◮ translation of data structures (Java classes, C unions, mutable

records...)? inference mechanism

◮ global analysis?

combine with other approaches

◮ separation logic to describe group region contents?

Conclusion 51 / 51