k. rustan m. leino microsoft research, redmond, wa, usa with mike barnett, robert deline, manuel...

24
K. Rustan M. Leino Microsoft Research, Redmond, WA, USA with Mike Barnett, Robert DeLine, Manuel Fahndrich, and Wolfram Schulte Toward Toward enforceable contracts enforceable contracts for .NET for .NET ¨ CASSIS 2004 Marseille, France 12 March 2004

Post on 21-Dec-2015

214 views

Category:

Documents


0 download

TRANSCRIPT

K. Rustan M. LeinoMicrosoft Research, Redmond, WA, USA

withMike Barnett, Robert DeLine,Manuel Fahndrich, and Wolfram Schulte

TowardTowardenforceable contractsenforceable contractsfor .NETfor .NET

TowardTowardenforceable contractsenforceable contractsfor .NETfor .NET

¨

CASSIS 2004Marseille, France12 March 2004

.NET primer for Java programmersType-safe programming languageManaged code

Java bytecode

Java Virtual Machine (JVM)

Common Language Runtime (CLR)

C#Visual BasicManaged C++Spec#

Common Intermediate Language (CIL)

also known asMicrosoft Intermediate Language (MSIL)

obj.myMethod()

obj.MyMethod()

Software engineering problem

Building and maintaining large systems that are correct

Approach

• Specifications record design decisions– bridge intent and code

• Tools amplify human effort– manage details– find inconsistencies– ensure quality

Design decisions– examples and trends

procedural abstractionint x;assert(x < a.Length); finite-state protocols SpecStrings

Pre- and postconditions, and object invariants

Acquire()

Acquire()Release()

Release()

int strlen(pre notnull char * str); 

void Copy(int[] a, int start, int count)requires start+count <= a.Length;

 

Contracts

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

valueA character array.

startIndexThe starting position in value.

charCountThe number of characters append.

Return Value

A reference to this instance after the append operation has occurred.

ExceptionsException Type Condition

ArgumentNullException value is a null reference, and startIndex and charCount are not zero.

ArgumentOutOfRangeException charCount is less than zero.

-or-

startIndex is less than zero.

-or-

startIndex + charCount is less than the length of value.

Contracts today

Spec# contractsPrecondition• Callers are expected to establish

precondition before invoking method• Implementations can assume

precondition holds on entry

Postcondition• Implementations are expected to

establish postcondition on exit• Callers can assume postcondition

upon return from method invocation

public StringBuilder Append( char[] value, int startIndex, int charCount);

requires value != null || (charCount == 0 && startIndex == 0); requires 0 <= charCount && 0 <= startIndex; requires startIndex + charCount <= value.Length;

ensures result == this;

Code + contracts in

Spec#

BoogieSpec# compiler

Compile-time error messages

Run-time exceptions

Spec# and Boogie

Boogie demo

Spec# is C# extended with:• Non-null types• Preconditions• Postconditions• Object invariants• Checked exceptions• ...

Spec#: Non-null types• T x;

The value of x is null ora reference to an object whose type is a subtype of T.

• T! y;The value of y isa reference to an object whose type is a subtype of T,not null.

Non-null instance fields

class C : B {T! x;public C(T! y): base(){

this.x = y;}public overrides int M() { return

x.f; }

Is this code type safe?

No! The base constructor can invoke the virtual method M and C.M would then find x to be null.

Non-null instance fields

class C : B {T! x;public C(T! y): x(y),

base(){}public overrides int M() { return

x.f; }

Need to allow x to beassigned before baseconstructor is called.

requires 0 <= startIndex otherwise ArgumentException;

Spec#: Parameter validation

public virtual StringBuilder Append(char[] value, int startIndex, int charCount)

Parameters

startIndexThe starting position in value.

Exceptions

Exception Type Condition

ArgumentException startIndex is less than zero.

-or-

;

requires 0 <= startIndex;

Parameter-validation exceptions

• requires 0 <= startIndex;• requires 0 <= startIndex

otherwise ArgumentException;• requires 0 <= startIndex

otherwise new ArgumentException(“startIndex”, Resource.Load(Resource. Description_StringBuilder_Append_arg_startIndex));

• precondition – caller obligation orpostcondition – implementation promise ?

• Complications for no good reason.E.g.: name no good without stack trace; name superfluous given stack trace

• precondition – caller obligation

Spec#: Taming exceptions• Introduce checked exceptions• An exception is checked if it

implements interface ICheckedException

Java Spec#•Throwable •Exception

•RuntimeException

• Error

Checked exceptions Unchecked exceptions

•ICheckedException

CheckedException

Spec#: Taming exceptions• Introduce checked exceptions• An exception is checked if it implements

interface ICheckedException• Methods must declare which checked

exceptions they may throw

int MyMethod()throws MyException;

int MyMethod()throws MyException ensures state==Closed;

Spec#: Taming exceptions• Introduce checked exceptions• An exception is checked if it implements

interface ICheckedException• Methods must declare which checked

exceptions they may throw• Soundness of throw statement

Exception x = new MyCheckedException();

throw x;If static type of x is not an ICheckedException, then check:

!( x is ICheckedException )

at run time.

Spec#: Object invariantsclass C {

int x, y;invariant x < y;

Joint work also with Peter Müller (ETH Zurich) and David Naumann (Stevens Institute of Technology)

Object invariant always holds, except possibly when the object is exposed

Spec#: Object invariantsclass C {

int x, y;invariant x < y;public void M(T! o) {

…expose (this) {

this.x = this.y;o.P();this.y++;

}…

}

The object invariant may be temporarily violated here

The object invariant is checked to hold here

Joint work also with Peter Müller (ETH Zurich) and David Naumann (Stevens Institute of Technology)

Spec#: Object invariantsclass C {

int x, y;invariant x < y;public void M(T! o) {

…expose (this) {

this.x = this.y;o.P();this.y++;

}…

}

The exposed/unexposed state of the object is recorded, so as to detect possible bad re-entrancy

Joint work also with Peter Müller (ETH Zurich) and David Naumann (Stevens Institute of Technology)

Boogie: Under the hood

Theoremprover

weakest-preconditiongenerator

translator

MSIL

BoogiePL

verification condition

Warnings

Inferenceengine

Boogie

Inference• Abstract interpretation• standard abstract domains: s+x < len• object fields: o.f < p.g• uninterpreted functions: i < Length(a)• combinations of abstract domains• special disjunctions: o.exposed ∨ o.f <

o.g• quantifications:

(∀o: T ・ o.f < o.g) (∀o: T ・ o.f = o.f0 ∨ o=x)

Summary• Spec# adds contracts to C#• Compiler inserts dynamic checks to

enforce contracts• Boogie enforces contracts statically

Evolution• C# managed code

Spec# non-null types, parameter validation

Boogie verification