Proving Copyless Message Passing

Proving Copyless Message Passing
Jules Villard 1
Étienne Lozes
1
1 LSV,
Cristiano Calcagno
ENS Cachan, CNRS
2 Imperial
College, London
Sept. 10. 2009
2
Outline
Copyless Message Passing
Language Highlights
Contracts
Local Reasoning for Copyless Message Passing
Separation Logic
Separation Logic Extended
Proofs in Separation Logic. . .
. . . Extended
Proof Sketch
Conclusion
Inspiration: Singularity [Fähndrich & al. '06]
Singularity: a research project and an operating system.
I No memory protection: all processes share the same address
space
I Memory isolation is veried at compile time (Sing] language)
I No shared resources. Instead, processes communicate by
copyless message passing
I Communications are ruled by contracts
I Many guarantees ensured by the compiler:
• race freedom (process isolation)
• contract obedience
• progress (?)
1 / 31
Sing] communication model
I
I
I
I
Channels are bidirectional and asynchronous
channel = pair of FIFO queues
Channels are made of two endpoints
similar to socket model
Endpoints are allocated, disposed of, and may be
communicated through channels
under some conditions, similar to internal mobility in π -calculus
Communications are ruled by user-dened contracts
similar to session types
2 / 31
Message Passing with copies
x
z
y
e
m
send(cell,e,m);
f
w
*z = receive(cell,f);
3 / 31
Message Passing with copies
x
z
y
e
m
send(cell,e,m);
f
w
*z = receive(cell,f);
3 / 31
Message Passing with copies
m
x
z
y
e
m
send(cell,e,m);
f
w
*z = receive(cell,f);
3 / 31
Message Passing with copies
m
x
z
y
e
m
send(cell,e,m);
f
w
*z = receive(cell,f);
3 / 31
Message Passing with copies
m
x
z
y
e
m
send(cell,e,m);
f
w
*z = receive(cell,f);
3 / 31
Message Passing with copies
x
z
y
e
m
send(cell,e,m);
f
m
w
*z = receive(cell,f);
3 / 31
Message Passing with copies
x
z
y
e
m
send(cell,e,m);
f
m
w
*z = receive(cell,f);
3 / 31
Copyless Message Passing (shared memory)
x
z
y
e
m
send(cell,e,m);
f
w
*z = receive(cell,f);
4 / 31
Copyless Message Passing (shared memory)
x
z
y
e
m
send(cell,e,m);
f
w
*z = receive(cell,f);
4 / 31
Copyless Message Passing (shared memory)
m
x
z
y
e
m
send(cell,e,m);
f
w
*z = receive(cell,f);
4 / 31
Copyless Message Passing (shared memory)
m
x
z
y
e
m
send(cell,e,m);
f
w
*z = receive(cell,f);
4 / 31
Copyless Message Passing (shared memory)
x
z
y
e
m
send(cell,e,m);
f
w
*z = receive(cell,f);
4 / 31
Copyless Message Passing (shared memory)
x
z
y
e
m
send(cell,e,m);
f
w
*z = receive(cell,f);
4 / 31
In this talk [APLAS'09]
I
Dene a simple model of this language
I
Provide a proof system based on Separation Logic
5 / 31
In this talk [APLAS'09]
I
Dene a simple model of this language
I
Provide a proof system based on Separation Logic
• Validate programs w.r.t. ownership
• Compositional approach
• Provide a tool for annotated programs
5 / 31
Syntax of the Programming Language
Expressions and Boolean Expressions
E ::= x ∈ Var | ` ∈ Loc | ε ∈ Endpoint | v ∈ Val
B ::= E = E | B and B | not B
Atomic commands
c ::=
x =E
| x = new() | dispose(x) | x = E→f | x→f = E | . . .
Programs
p ::= c | p ; p | p ||p | if B then p else p | while B {p } | local x in p
6 / 31
Syntax of atomic commands (continued)
c ::= ...
| (e, f) = open(C)
| close (E,E')
| send(m, E, E')
| x = receive(m, E)
(creates a channel with endpoints e,f)
(channel disposal)
(sends message m over endpoint E)
(receives message m over endpoint E)
Comments
I
m is a message identier, not the value of the message
I
both endpoints of a channel must be closed together
7 / 31
A very simple example
local e , f in
(e , f ) = open ( C );
send (m ,e , a );
b = receive (m , f );
close (e , f );
≈
b = a;
9 / 31
Channels, Contracts
Processes communicate through channels.
I A channel is made of two endpoints.
I It is bidirectional and asynchronous.
I It must follow a contract.
Contracts dictate which sequences of messages are admissible.
I It is a nite state machine, where arrows are labeled by a
message's name and a direction: send (!) or receive (?).
I Dual endpoints of a channel follow dual contracts
(C̄ = C [? ↔!]).
I We consider leak-free contracts that ensure absence of
memory leaks
10 / 31
Contract Example
message ack
message cell
message close_me
contract C {
initial state transfer { ! cell -> wait ;
! close_me -> end ; }
state wait { ? ack -> transfer ; }
final state end {}
}
!cell
C:
transfer
?ack
!close_me
wait_ack
end
12 / 31
Our tool
heaps that hop!
Outline
Copyless Message Passing
Language Highlights
Contracts
Local Reasoning for Copyless Message Passing
Separation Logic
Separation Logic Extended
Proofs in Separation Logic. . .
. . . Extended
Proof Sketch
Conclusion
Separation Logic
Separation Logic [O'Hearn 01, Reynolds 02, . . . ]
I
I
An assertion language to describe states
An extension of Hoare Logic
15 / 31
Assertion Language
Syntax
E ::= x | n ∈ N
A ::= E1 = E2 | E1 6= E2
| emph | E1 7→ E2
| A1 ∧ A2 | A1 ∗ A2
expressions
stack predicates
heap predicates
formulas
Semantics
(s , h) (s , h) (s , h) (s , h) (s , h) E1 = E2 i JE1 Ks = JE2 Ks
i dom(h) = ∅
E1 7→ E2 i dom(h) = {JE1 Ks } & h(JE1 Ks ) = JE2 Ks
A1 ∧ A2 i (s , h) A1 & (s , h) A2
A1 ∗ A2 i ∃h1 , h2 . dom(h1 ) ∩ dom(h2 ) = ∅
& h = h1 ∪ h2
& (s , h1 ) A1 & (s , h2 ) A2
emph
16 / 31
Assertion Language (extension)
Syntax (continued)
A ::= . . .
peer
| empep | E 7→ (C {a}, E 0 )
endpoints' predicates
Intuitively E peer
7→ (C {a}, E 0 ) means :
I E is an allocated endpoint
I its peer is E 0
I it is ruled by contract C
I it currently is in contract's state a
17 / 31
True/False
1.
2.
3.
4.
x
x
x
x
7→ d : 10 ∗ y 7→ d : 11
7→ d : 10 ∧ y 7→ d : 11
7→ d : 10 ∧ y 7→ d : 10
peer
7→ − ∧ x 7→ (−, −)
satisable, 2 cells
false
satisable, x = y
false
18 / 31
Soundness
Theorem 1 (Soundness)
If a Hoare triple {A} p {B } is provable, then if the program p
starts in a state satisfying A and terminates,
1. p does not fault on memory accesses
2. p does not leak memory
3. the nal state satises B
19 / 31
Proof System
Standard Hoare Logic
{A} p {A0 }
{A0 } p 0 {B }
{A} p ; p 0 {B }
...
Local Reasoning Rules
{A} p {B }
{A ∗ F } p {B ∗ F }
{A} p {B }
{A0 } p 0 {B 0 }
{A ∗ A0 } p ||p 0 {B ∗ B 0 }
Small Axioms
{A} x = E {A[x ←x 0 ] ∧ x = E [x ←x 0 ]}
{emp} x = new() {∃v . x 7→ v }
...
20 / 31
Proof of Programs
{ x 7→ d : 10 }
y = new ();
{ x 7→ d : 10 ∗ y 7→ − }
y - > d = 42;
{ x 7→ d : 10 ∗ y 7→ d : 42 }
dispose ( x );
{ y 7→ d : 42 }
x = y;
{ x 7→ d : 42 ∧ x = y }
22 / 31
Proof System (extended)
Standard Hoare Logic
Unchanged.
Local Reasoning Rules
Unchanged.
Small Axioms
Small axioms added for new commands.
23 / 31
Annotating Messages
I
We have to know the contents of messages
Each message m appearing in a contract is described by a
formula Im of our logic.
I
Im may refer to two special variables:
I
• val will denote the location of the message in memory
• src will denote the location of the sending endpoint
24 / 31
Small Axioms for Communications
Receive rule:
?m
a −→ b ∈ C
peer
peer
{E 7→ (C {a}, f )} x = receive(m, E) {E 7→ (C {b}, f ) ∗ Im (x , f )}
25 / 31
Small Axioms for Communications
Send rules:
!m
a −→ b ∈ C
peer
peer
0
{E 7→ (C {a}, −) ∗ Im (E , E )} send(E.m,E') {E 7→ (C {b}, −)}
!m
a −→ b ∈ C
peer
peer
{E 7→ (C {a}, −) ∗ (E 7→ (C {b}, −) −
−∗ Im (E 0 , E ))}
send(E.m,E')
{emp}
25 / 31
Small Axioms for Communications
Open and Close rules:
i = init(C )
peer
peer
{emp} (e, f) = open(C) {e 7→ (C {i }, f ) ∗ f →
7 (C̄ {i }, e )}
f ∈ nal(C )
{E →
7 (C {f }, E ) ∗ E 7→ (C̄ {f }, E )} close (E,E') {emp}
peer
0
0 peer
25 / 31
Back to Contracts
I
Why is the close rule sound?
f ∈ nal(C )
{E →
7 (C {f }, E ) ∗ E 7→ (C̄ {f }, E )} close (E,E') {emp}
peer
0
0 peer
Leak-free Contracts
A contract C is leak-free if whenever both ends of a channel ruled
by C are in the same nal state, there are no pending messages in
the channel.
26 / 31
Properties of Contracts
Denition 2 (Synchronizing state)
A state s is synchronizing if every cycle that goes through it
contains at least one send and one receive.
!m1
a
!m1
b
!m2
a
b
?m2
27 / 31
Properties of Contracts
Denition 2 (Synchronizing state)
Denition 3 (Determinism)
Two distinct edges in a contract must be labeled by dierent
messages.
a
!m
b
!m
c
a
!m
b
!m 0
c
a
!m
b
?m
c
27 / 31
Properties of Contracts
Denition 2 (Synchronizing state)
Denition 3 (Determinism)
Denition 4 (Uniform choice)
All outgoing edges from a same state in a contract must be either
all sends or all receives.
a
!m1
b
?m2
c
a
!m1
b
!m2
c
27 / 31
Properties of Contracts
Denition 2 (Synchronizing state)
Denition 3 (Determinism)
Denition 4 (Uniform choice)
Lemma 5 (Half-Duplex)
Lemma 6 (Leak-free)
3 & 4 ⇒ communications are
nal states are synchronizing and
communications are half-duplex
⇒ contract is leak-free
half-duplex.
27 / 31
Soundness
Theorem 7 (Soundness for Copyless Message Passing)
If a Hoare triple {A} p {B } is provable and the contracts are leak
free, then if the program p starts in a state satisfying A and
terminates,
1. contracts are respected
2. p does not fault on memory accesses
3. p does not leak memory
4. the nal state satises B
5. there is no race
6. no communication error occur
7. there is no deadlock
28 / 31
Soundness
Theorem 7 (Soundness for Copyless Message Passing)
If a Hoare triple {A} p {B } is provable and the contracts are leak
free, then if the program p starts in a state satisfying A and
terminates,
1. contracts are respected
2. p does not fault on memory accesses
3. p does not leak memory
thanks to contracts!
4. the nal state satises B
5. there is no race
6. no communication error occur
thanks to contracts!
7. there is no deadlock
28 / 31
Soundness
Theorem 7 (Soundness for Copyless Message Passing)
If a Hoare triple {A} p {B } is provable and the contracts are leak
free, then if the program p starts in a state satisfying A and
terminates,
1. contracts are respected
2. p does not fault on memory accesses
3. p does not leak memory
thanks to contracts!
4. the nal state satises B
5. there is no race
6. no communication error occur
thanks to contracts!
7. there is no deadlock
not yet. . .
28 / 31
Proof of the Example
// list (x)
local e , f ;
(e , f ) = open ( C );
// list (x) * e | - >( C{i} ,f) * f | - >( C{i} ,e)
// ( list (x )* e | - >( C{i} ,f )) * (f | - >( C{i} ,e ))
local t ;
local y , e =0;
while ( x != null ) {
while ( e == 0) {
t = x - > tl ;
{ y = receive ( cell , f );
send ( cell , e , x );
dispose ( y );
x = t;
send ( ack , f );
||
receive ( ack , e ); }
} + {
send ( close_me , e , e );
e = receive ( close_me , f );
}}
close (e , f );
30 / 31
Proof of the Example
// list (x) * e | - >( C{i} ,f)
local t ;
while ( x != null ) {
t = x - > tl ;
send ( cell , e , x );
x = t;
receive ( ack , e ); }
send ( close_me , e , e );
30 / 31
Proof of the Example
// list (x) * e | - >( C{i} ,f)
local t ;
while ( x != null ) {
// x| - > Y * ls (Y) * e | - >( C{i} ,f)
t = x - > tl ;
// x| - > Y * ls (Y) * e | - >( C{i} ,f) /| t=Y
send ( cell , e , x );
// list (t) * e | - >( C{ ack } ,f)
x = t;
receive ( ack , e ); }
// e | - >( C{ transfer } ,f)
send ( close_me , e , e );
// emp
30 / 31
Proof of the Example
// list (x)
local e , f ;
(e , f ) = open ( C );
// list (x) * e | - >( C{i} ,f) * f | - >( C{i} ,e)
// ( list (x )* e | - >( C{i} ,f )) * (f | - >( C{i} ,e ))
local t ;
local y , e =0;
while ( x != null ) {
while ( e == 0) {
t = x - > tl ;
{ y = receive ( cell , f );
send ( cell , e , x );
dispose ( y );
x = t;
send ( ack , f );
||
receive ( ack , e ); }
} + {
send ( close_me , e , e );
e = receive ( close_me , f );
}}
close (e , f );
30 / 31
Proof of the Example
// list (x)
local e , f ;
(e , f ) = open ( C );
// list (x) * e | - >( C{i} ,f) * f | - >( C{i} ,e)
// ( list (x )* e | - >( C{i} ,f )) * (f | - >( C{i} ,e ))
local t ;
local y , e =0;
while ( x != null ) {
while ( e == 0) {
t = x - > tl ;
{ y = receive ( cell , f );
send ( cell , e , x );
dispose ( y );
x = t;
send ( ack , f );
||
receive ( ack , e ); }
} + {
send ( close_me , e , e );
e = receive ( close_me , f );
// emp
}}
close (e , f );
30 / 31
Proof of the Example
// f | - >( C{i} ,e)
local x , e =0;
while ( e == 0) {
{ x = receive ( cell , f );
dispose ( x );
send ( ack , f );
} + {
e = receive ( close_me , f );
}
}
close (e , f );
30 / 31
Proof of the Example
// f | - >( C{i} ,e)
local x , e =0;
// f | - >( C{i} ,e) /| e =0
while ( e == 0) {
// f | - >( C{i} ,e) /| e =0
{ x = receive ( cell , f );
// f | - >( C{ ack } ,e) * x | - > dispose ( x );
// f | - >( C{ ack } ,e)
send ( ack , f );
} + {
e = receive ( close_me , f );
// f | - >( C{ end } ,e) * e | - >( C{ end } ,f)
}
}
// f | - >( C{ end } ,e) * e | - >( C{ end } ,f)
close (e , f );
// emp
30 / 31
Proof of the Example
// list (x)
local e , f ;
(e , f ) = open ( C );
// list (x) * e | - >( C{i} ,f) * f | - >( C{i} ,e)
// ( list (x )* e | - >( C{i} ,f )) * (f | - >( C{i} ,e ))
local t ;
local y , e =0;
while ( x != null ) {
while ( e == 0) {
t = x - > tl ;
{ y = receive ( cell , f );
send ( cell , e , x );
dispose ( y );
x = t;
send ( ack , f );
||
receive ( ack , e ); }
} + {
send ( close_me , e , e );
e = receive ( close_me , f );
// emp
}}
close (e , f );
30 / 31
Proof of the Example
// list (x)
local e , f ;
(e , f ) = open ( C );
// list (x) * e | - >( C{i} ,f) * f | - >( C{i} ,e)
// ( list (x )* e | - >( C{i} ,f )) * (f | - >( C{i} ,e ))
local t ;
local y , e =0;
while ( x != null ) {
while ( e == 0) {
t = x - > tl ;
{ y = receive ( cell , f );
send ( cell , e , x );
dispose ( y );
x = t;
send ( ack , f );
||
receive ( ack , e ); }
} + {
send ( close_me , e , e );
e = receive ( close_me , f );
// emp
}}
close (e , f );
// emp
30 / 31
Proof of the Example
// list (x)
local e , f ;
(e , f ) = open ( C );
// list (x) * e | - >( C{i} ,f) * f | - >( C{i} ,e)
// ( list (x )* e | - >( C{i} ,f )) * (f | - >( C{i} ,e ))
local t ;
local y , e =0;
while ( x != null ) {
while ( e == 0) {
t = x - > tl ;
{ y = receive ( cell , f );
send ( cell , e , x );
dispose ( y );
x = t;
send ( ack , f );
||
receive ( ack , e ); }
} + {
send ( close_me , e , e );
e = receive ( close_me , f );
// emp
}}
close (e , f );
// emp
// emp
30 / 31
Conclusion
In this Talk
I
I
I
I
[APLAS'09]
Formalization of heap-manipulating, message passing programs
with contracts
Contracts help us to ensure the absence of memory leaks
Proof system
Tool to prove specications: Heap-Hop
31 / 31
Conclusion
In this Talk
I
I
I
I
I
[APLAS'09]
Formalization of heap-manipulating, message passing programs
with contracts
Contracts help us to ensure the absence of memory leaks
Proof system
Tool to prove specications: Heap-Hop
Not in this talk: semantics (based on abstract separation logic)
31 / 31
Conclusion
In this Talk
I
I
I
I
I
[APLAS'09]
Formalization of heap-manipulating, message passing programs
with contracts
Contracts help us to ensure the absence of memory leaks
Proof system
Tool to prove specications: Heap-Hop
Not in this talk: semantics (based on abstract separation logic)
In a Future Talk
I
I
Contracts help us to ensure the absence of deadlocks
Tackle real case studies: Singularity, MPI, distributed GC, . . .
31 / 31