Foundations of Concurrent Program Verification

 
K. Rustan M. Leino
RiSE, Microsoft Research, Redmond
joint work with Peter M
ü
ller and Jan Smans
 
Lecture 0
1 September 2009
FOSAD 2009, Bertinoro, Italy
 
Prove program correctness
for all possible inputs and behaviors
 
Prove parts of a program separately
Correctness of every part
 
implies
correctness of whole program
 
Record programmer design decisions
Describe usage of program constructs
Provide redundancy
Enable modular verification
 
Specification and verification methodology
Describes properties of the heap
Active area of research
Ownership
Spec#, Java+JML, vcc, type systems, …
Dynamic frames
VeriCool, Dafny
Permissions (capabilities)
Effect systems, separation logic, VeriCool 3,
Chalice, …
 
Interleaving of thread executions
Unbounded number of:  threads, locks, …
We need some basis for doing the
reasoning
A way of thinking!
 
Concurrent programs
Features like:  threads, monitors, abstraction
as well as:  objects, methods, loops, …
Avoid errors like:  race conditions, deadlocks
Specifications with permissions
Building a program verifier
 
Pre- and postconditions
 
Loop invariants
 
Chalice
 
Helps testing find bugs more quickly
Optional, they can be treated as ghosts
If they are to be ghosted, specifications
must have no side effects (on non-ghost
state)
 
Access to a memory location requires
permission
Permissions are held by activation records
Syntax for talking about permission to y:
acc
(y)
 
Permissions
acc
(c.y)
 
A specification expression can mention a
memory location only if it also entails the
permission to that location
acc
(y) && y < 100
 
y < 100
 
acc
(x) && y < 100
 
acc
(o.y) && p.y < 100
 
o == p && 
acc
(o.y) && p.y < 100
 
x / y < 20
 
y ≠ 0 && x / y < 20
 
 
A loop iteration is like its own activation
record
 
 
 
is like
 
Loop invariants with permissions
 
Threads run concurrently
A new thread of control is started with the
fork
 statement
A thread can wait for another to complete
with the 
join 
statement
Permissions are transferred to and from a
thread via the starting method’s pre- and
postconditions
 
Fork and join
 
call  ==  fork + join
 
 
 
is semantically like
 
 
 
 
… but is implemented more efficiently
 
Parallel computation
 
Recall:
A specification expression can mention a
memory location only if it also entails
some permission to that location
 
Example:  
acc
(y) && y < 100
 
 
Without any permission to y, other threads
may change y, and then y would not be
stable
 
acc
(y)
 
write permission to y
rd
(y)
 
read permission to y
 
At any one time, at most one thread can
have write permission to a location
 
Parallel reads
 
acc
(y)
 
100% permission to y
acc
(y, p)
 
p% permission to y
rd
(y)
 
read permission to y
Write access requires 100%
Read access requires >0%
                     =                      +
                     
acc
(y)
acc
(y,69)
acc
(y,31)
rd
(y)
acc
(y,
)
 
method
 M() 
requires
 
acc
(y) 
ensures
 
acc
(y)
can change y
Can
method
 P() 
requires
 
rd
(y) 
ensures
 
rd
(y)
change y?
That is, can we prove:
 
Demo: NoPerm
 
What if two threads want write access to
the same location?
acc
(c.y)
 
acc
(c.y)
acc
(y)
 
Like other specifications, can hold both
permissions and conditions
Example:  
invariant
 
acc
(y) && 0 <= y
acc
(y)
 
 
Monitors
 
The concepts
holding a lock, and
having permissions
   are orthogonal to one another
In particular:
Holding a lock does not imply any right to
read or modify shared variables
Their connection is:
Acquiring a lock obtains some permissions
Releasing a lock gives up some permissions
 
Server-side locking
“safer” (requires less thinking)
 
 
 
 
Client-side locking
more efficient
Slide Note

© 2007 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.

The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation.

MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.

Embed
Share

Explore the importance of program verification methodologies, modular verification, and specification styles in ensuring the correctness of concurrent programs. Learn about key concepts like pre- and postconditions, loop invariants, and the role of specifications in bug detection and testing.

  • Program Verification
  • Concurrent Programs
  • Modular Verification
  • Specification Styles
  • Bug Testing

Uploaded on Oct 01, 2024 | 1 Views


Download Presentation

Please find below an Image/Link to download the presentation.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.

You are allowed to download the files provided on this website for personal or commercial use, subject to the condition that they are used lawfully. All files are the property of their respective owners.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.

E N D

Presentation Transcript


  1. A Foundation for Verifying Concurrent Programs K. Rustan M. Leino RiSE, Microsoft Research, Redmond joint work with Peter M ller and Jan Smans Lecture 0 1 September 2009 FOSAD 2009, Bertinoro, Italy

  2. Program verification Prove program correctness for all possible inputs and behaviors

  3. Modular verification Prove parts of a program separately Correctness of every part implies correctness of whole program

  4. Specifications Record programmer design decisions Describe usage of program constructs Provide redundancy Enable modular verification

  5. Specification style Specification and verification methodology Describes properties of the heap Active area of research Ownership Spec#, Java+JML, vcc, type systems, Dynamic frames VeriCool, Dafny Permissions (capabilities) Effect systems, separation logic, VeriCool 3, Chalice,

  6. Concurrent programs Interleaving of thread executions Unbounded number of: threads, locks, We need some basis for doing the reasoning A way of thinking!

  7. These lectures Concurrent programs Features like: threads, monitors, abstraction as well as: objects, methods, loops, Avoid errors like: race conditions, deadlocks Specifications with permissions Building a program verifier

  8. Square Pre- and postconditions

  9. Cube Loop invariants

  10. ISqrt Chalice

  11. Specifications at run time Helps testing find bugs more quickly Optional, they can be treated as ghosts If they are to be ghosted, specifications must have no side effects (on non-ghost state)

  12. Dealing with memory (the heap) Access to a memory location requires permission Permissions are held by activation records Syntax for talking about permission to y: acc(y)

  13. Inc Permissions

  14. Transfer of permissions method Main() { var c := new Counter; call c.Inc(); } method Inc() requiresacc(y) ensuresacc(y) { y := y + 1; }

  15. Well-formed specifications A specification expression can mention a memory location only if it also entails the permission to that location acc(y) && y < 100 y < 100 acc(x) && y < 100 acc(o.y) && p.y < 100 o == p && acc(o.y) && p.y < 100 x / y < 20 y 0 && x / y < 20

  16. Loop invariants and permissions A loop iteration is like its own activation record Before; while (B) invariant J { S; } After; is like Before; call MyLoop( ); After; method MyLoop( ) requires J ensures J { if (B) { S; call MyLoop( ); } }

  17. Loop invariant: example method M() requiresacc(x) && acc(y) && x <= 100 && y <= 100 { while (y < 100) invariantacc(y) && y <= 100 { y := y + 1; x := x + 1; // error: no permission to access x } assert x <= y; }

  18. Loop invariant: example method M() requiresacc(x) && acc(y) && x <= 100 && y <= 100 { while (y < 100) invariantacc(y) && y <= 100 { y := y + 1; } assert x <= y; }

  19. ISqrtwith fields Loop invariants with permissions

  20. Threads Threads run concurrently A new thread of control is started with the fork statement A thread can wait for another to complete with the join statement Permissions are transferred to and from a thread via the starting method s pre- and postconditions

  21. ForkInc Fork and join

  22. The two halves of a call call == fork + join call x,y := o.M(E, F); is semantically like fork tk := o.M(E, F); join x,y := tk; but is implemented more efficiently

  23. TwoSqrts Parallel computation

  24. Well-formed revisited Recall: A specification expression can mention a memory location only if it also entails some permission to that location Example: acc(y) && y < 100 Without any permission to y, other threads may change y, and then y would not be stable

  25. Read permissions acc(y) write permission to y rd(y) read permission to y At any one time, at most one thread can have write permission to a location

  26. VideoRental Parallel reads

  27. Fractional permissions acc(y) 100% permission to y acc(y, p) p% permission to y rd(y) read permission to y Write access requires 100% Read access requires >0% = +

  28. Implicit dynamic frames method M() requires acc(y) ensures acc(y) can change y Can method P() requires rd(y) ensures rd(y) change y? That is, can we prove: method Q() requiresrd(y) && y == 5 { call P(); assert y == 5; } Demo: NoPerm

  29. Shared state What if two threads want write access to the same location? methodA() { y := y + 21; } class Fib { var y: int; method Main() { var c := new Fib; fork c.A(); fork c.B(); } } ? methodB() { y := y + 34; }

  30. Monitors methodA() { acquirethis; y := y + 21; releasethis; } class Fib { var y: int; invariantacc(y); method Main() { var c := new Fib; share c; fork c.A(); fork c.B(); } } methodB() { acquirethis; y := y + 34; releasethis; }

  31. Monitor invariants Like other specifications, can hold both permissions and conditions Example: invariant acc(y) && 0 <= y

  32. Object life cycle share thread local shared, available new release acquire shared, locked

  33. SharedCounter Monitors

  34. Locks and permissions The concepts holding a lock, and having permissions are orthogonal to one another In particular: Holding a lock does not imply any right to read or modify shared variables Their connection is: Acquiring a lock obtains some permissions Releasing a lock gives up some permissions

  35. Thread-safe libraries Server-side locking safer (requires less thinking) invariant acc(y); method M() requirestrue { acquirethis; y := ; releasethis; } Client-side locking more efficient method M() requiresacc(y) { y := ; }

Related


More Related Content

giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#