K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond, WA, USA 15 January 2009 Séminaire Digiteo Orsay, France
Research in Software Engineering Microsoft Research, Redmond Related groups: PPT (MSR Cambridge) and RSE (MSR India)
Goal Better build, maintain, and understand programs How? Specifications Tools, tools, tools Program semantics Verification-condition generation, symbolic execution, model checking, abstract interpretation, fuzzing, test generation Satisfiability Modulo Theories (SMT)
Hoare, Joshi, Leavens, Misra, Naumann, Shankar, Woodcock, et al. “We envision a world in which computer programs are always the most reliable component of any system or device that contains them” [Hoare & Misra]
Spec# demo Various techniques and RiSE tools Use/effectiveness of tools at Microsoft
Research prototype Spec# language Object-oriented.NET language Superset of C# 2.0, adding: more types (e.g., non-null types) specifications (e.g., pre- and postconditions) Usage rules (methodology) Checking: Static type checking Run-time checking Static verification (optional)
StringBuilder.Append Method (Char[ ], Int32, Int32) Appends the string representation of a specified subarray of Unicode characters to the end of this instance. public StringBuilder Append(char[] value, int startIndex, int charCount); Parameters value A character array. startIndex The starting position in value. charCount The number of characters append. Return Value A reference to this instance after the append operation has occurred. Exceptions Exception TypeCondition ArgumentNullExceptionvalue is a null reference, and startIndex and charCount are not zero. ArgumentOutOfRangeExceptioncharCount is less than zero. -or- startIndex is less than zero. -or- startIndex + charCount is less than the length of value.
public StringBuilder Append(char[] value, int startIndex, int charCount ); requires value == null ==> startIndex == 0 && charCount == 0; requires 0 <= startIndex; requires 0 <= charCount; requires value == null || startIndex + charCount <= value.Length; ensures result == this; Exception TypeCondition ArgumentNullExceptionvalue is a null reference, and startIndex and charCount are not zero. ArgumentOutOfRangeExceptioncharCount is less than zero. -or- startIndex is less than zero. -or- startIndex + charCount is less than the length of value.
public StringBuilder Append(char[] value, int startIndex, int charCount ) { Contract.Requires(value != null || (startIndex == 0 && charCount == 0)); Contract.Requires(0 <= startIndex); Contract.Requires(0 <= charCount); Contract.Requires(value == null || startIndex + charCount <= value.Length); Contract.Ensures(Contracts.Result () == this); // method implementation... } Note that postcondition is declared at top of method body, which is not where it should be executed. A rewriter tool moves these.
Declarative contracts Language independent Library to ship in.NET 4.0 Tools to be released via DevLabs Code Contracts Rewriter (for run-time checking) Clousot abstract interpreter Pex automated testing tool
MSIL (“bytecode”) SMT solver V.C. generator Inference engine Translator verification condition “correct” or list of errors Spec# compiler Spec# Boogie
Spec#Spec# C with HAVOC specifications DafnyDafny C with vcc specifications ChaliceChalice Z3Z3SimplifySimplify SMT Lib BoogieBoogie Boogie-to-Boogie transformations: Inference enginesInference engines Program transformationsProgram transformations Logic optimizersLogic optimizers Boogie-to-Boogie transformations: Inference enginesInference engines Program transformationsProgram transformations Logic optimizersLogic optimizers Your language here Your prover here Isabelle/ HOL
Verification conditions computed by weakest preconditions (wp) wp( Prog, Q ) yields a formula that describes the pre-states from which Prog correctly establishes Q Example: wp( if (B) { S } else { T }, Q ) = ( B wp( S, Q)) ( ¬ B wp( T, Q))
Example program ( Prog ): p := new C(); if (x < 0) { x := -x; } assert p ≠ null; wp( Prog, true ) =((x<0 (p≠null)[-x/x]) ( ¬ (x<0) p≠null))[newC()/p] = ((x<0 newC()≠null) ( ¬ (x<0) newC()≠null)
Rewrite Prog into Prog’ : assume p 0 = newC(); if (x 0 < 0) { assume x 1 = -x 0 ; assume x 2 = x 1 ; } else { assume x 2 = x 0 ; } assert p 0 ≠ null; wp( Prog’, true ) = p 0 =newC() ((x 0 <0 x 1 = -x 0 x 2 = x 1 ) ( ¬ (x 0 <0) x 2 = x 0 )) p 0 ≠ null
Works well when the if branches modify variables that the downstream assertion does not depend on But when encoding the heap as one variable, almost every branch modifies that variable … room for new solutions
Demo: Chunker.dict
dict: :Chunker:Chunker :Dictionary:Dictionary n: 84 Count: 21 :Chunker:Chunker dict: n: 20 inv dict.Count ≤ n; :Classroom:Classroom studentGrades: inv studentGrades.Count ≤ 20; reprep inv dict.Count ≤ n; owner
Spec#/Boogie methodology Dynamic frames Implicit dynamic frames Separation logic … room for improved encodings and methodologies
Abstract interpreter for.NET Verifies Code Contracts at compile time Some key technology: Heap-aware abstraction Iterative application of numerical domains: Pentagons Subpolyhedra others
Some common abstract domains: Intervalsx [A,B] Octagons x y ≤ K PolyhedraΣ i x i ≤ K Observation: Checking array accesses involves constraints like 0 ≤ x < a.Length These can be represented by intervals plus variable orderings y ≤ x Picture source: Robert Webb's Great Stella software, Pentagon:
Sage [Godefroid, Levin, et al.] White-box fuzzing for C programs Pex [de Halleux, Tillman, et al.] Automatic white-box testing for.NET Seed input New generation of symbolically derived input
Satisfiability Modulo Theories (SMT) solver 9 first places and 6 second places at SMT-COMP’08 Used in all tools mentioned, except Clousot
Static Driver Verifier (SDV) Applied regularly to all Microsoft device drivers of the support device models ~300 bugs found Available to third parties in Windows DDK Sage Applied regularly 100s of people doing various kinds of fuzzing HAVOC Has been applied to 100s of KLOC ~40 bugs in resource leaks, lock usage, use-after-free vcc Being applied to Microsoft Hypervisor …
Machine-processable specifications are being used increasingly Tools are useful and necessary Provide useful checking Both validate and drive research SMT solving is a key technology Trend: user input is moving toward program text Many research challenges