Title: Advanced programming tools at Microsoft
1Advanced programming tools at Microsoft
- K. Rustan M. LeinoMicrosoft Research, Redmond,
WA, USA
16 May 2005Distinguished lecture, York
UniversityToronto, ON, Canada
2Software engineering problem
- Building and maintaining large systems that are
correct
3Approach
- Specifications record design decisions
- bridge intent and code
- Tools amplify human effort
- manage details
- find inconsistencies
- ensure quality
4Design decisions examples and trends
- procedural abstraction
- int x
- assert(x lt a.Length)
- finite-state protocols
- mark-ups
- pre- and postconditions, and object
invariants
5More powerful techniquesa selection
- 0. PREfix
- 1. SLAM
- 2. SpecStrings
- 3. Spec
60. PREfix
Bush, Pincus, Sielaff, et al.
- Detects common errors in C/C
- incorrect usage of null pointers, memory
allocation, uninitialized variables, library
idioms, ... - Performs symbolic execution
- detailed C semantics
- paths simulated in detail, not all paths
simulated - interprocedural, procedures summarized by small
subset of their paths
7PREfix example
- int abs(int x) int y if (0 lt x) y
x return y
possible use ofuninitialized variable
8PREfix virtues
- Expensive to run
- whole-program analysis
- Reduces effects of spurious warnings
- filters and prioritizes output, uses heuristics
- Effective at finding errors
- 1/8 of bugs fixed in Windows Server 2003 found by
PREfix (and PREfast) - Widely deployed
9The PREfast revolution
Weise, et al.
- PREfast framework for authoring analyses (walks
AST) - PREfix runs centrally after check-ins,PREfast
can run on developer desktops before check-ins - Name recognition, plug-ins
10On the road to embracing static analysisPREfix
milestone
- PREfix and PREfast have openedeyes of
developers and managementto power of
compile-time checking
111. Niche device drivers
- bugs can have severe effects
- relatively small code base (usually 50 KLOC)
- crash-freedom specified by finite-state API
protocols - correctness mostlydepends on flow ofcontrol,
not data
Acquire()
Release()
Acquire()
Release()
12SLAM
Ball, Rajamani, et al.
- Software model checking
- predicate abstraction
- model checking (state exploration)
- counterexample-driven predicate refinement
13Predicate abstraction and refinement
correct
modelchecker
boolean program
abstract trace
predicateabstraction
concrete trace
C program
predicates
feasible?
no
yes
error message
predicaterefinement
14SLAM example
Acquire()
- do
- KeAcquireSpinLock()
- nPacketsOld nPackets
-
- if (request)
- request request-gtNext
- KeReleaseSpinLock()
- nPackets
-
- while (nPackets ! nPacketsOld)
- KeReleaseSpinLock()
Release()
Acquire()
Release()
15SLAM example
- Predicates
- P spin lock held
- do
- assert P P true // KeAcquireSpinLock()
-
-
- if ( )
-
- assert P P false //
KeReleaseSpinLock() -
-
- while ( )
- assert P P false // KeReleaseSpinLock()
16SLAM example
- Predicates
- P spin lock held
- do
- assert P P true
-
-
- if ( )
-
- assert P P false
-
-
- while ( )
- assert P P false
error path in abstract program
17SLAM example
- Predicates
- P spin lock held
- do
- KeAcquireSpinLock()
- nPacketsOld nPackets
-
- if (request)
- request request-gtNext
- KeReleaseSpinLock()
- nPackets
-
- while (nPackets ! nPacketsOld)
- KeReleaseSpinLock()
infeasible path in concrete program
error path in abstract program
18SLAM example
- Predicates
- P spin lock held
- Q nPackets nPacketsOld
- do
- KeAcquireSpinLock()
- nPacketsOld nPackets
-
- if (request)
- request request-gtNext
- KeReleaseSpinLock()
- nPackets
-
- while (nPackets ! nPacketsOld)
- KeReleaseSpinLock()
infeasible path in concrete program
error path in abstract program
19SLAM example
- Predicates
- P spin lock held
- Q nPackets nPacketsOld
- do
- assert P P true
- Q true // nPacketsOld nPackets
-
- if ( )
-
- assert P P false
- Q if Q then false else end //
nPackets -
- while ( Q) // nPackets ! nPacketsOld
- assert P P false
no error path in abstract programhence,
concrete program is correct
20SLAM at Microsoft
- finite-state API protocols specified by experts
- applied to 100s of Windows drivers,for 10s of
rules, found 60 errors - Static Driver Verifier
- transferred to WindowsDriver Quality group
- to be released in DDK
21On the road to embracing static analysisSLAM
milestone
- SLAM showcases specifications and powerful
checking
222. SpecStrings
Das, Fähndrich, et al.
- company-wide effort to annotate C/C APIs
- standard annotation language (SAL) for describing
assumptions about parameters - limited checking by PREfast plug-in
- can catch some null problems and buffer overruns
23SpecString example
- void memcpy(
- pre notnull
- pre writableTo(pre byteCount(num))
- post readableTo(pre byteCount(num))
- void dest,
- pre notnull
- pre readableTo(pre byteCount(num))
- void src,
- size_t num)
24SpecStrings at Microsoft
- emphasizes importance of interfaces
- better documentation
- improves checking
- fewer spurious warnings
- can detect errors from violations of stated intent
25On the road to embracing static
analysisSpecStrings milestone
- With SpecStrings, developers become used to
source-code annotations that go beyond what
compiler requires
263. Into the future
- managed code (C, )
- involve developers more intimately
- capture design decisions earlier
- let developers take control of their code
- reach beyond checking limits of current tools
27Spec
- Experimental mix of contracts and tool support
- Aimed at experienced developers who know the high
cost of testing and maintenance - Superset of C
- non-null types
- pre- and postconditions
- object invariants
- Tool support
- more type checking
- compiler-emitted run-time checks
- static program verification
contracts everywhere
C
into the future
type checking
static verification
run-time checks
degree of checking,effort
28Specifications today
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
29Spec specifications
- Precondition
- Callers are expected to establish precondition
before invoking method - Implementations can assume precondition holds
on entry
public StringBuilder Append( char value,
int startIndex, int charCount)
requires value ! null (startIndex 0
charCount 0) requires 0 lt startIndex
0 lt charCount requires startIndex
charCount lt value.Length ensures result
this
- Postcondition
- Implementations are expected to establish
postcondition on exit - Callers can assume postcondition upon return
from method invocation
30Object invariants
readonly int rowsreadonly int columnsreadonly
double, m readonly int numInitialVarsreadonly
int numSlackVarsreadonly int
rhsColumn readonly ArrayListltobjectgt
dimsreadonly int basisColumnsreadonly int
inBasisbool constructionDone false invariant
rows m.GetLength(0)invariant 1 lt columns
columns m.GetLength(1)invariant 0 lt
numInitialVarsinvariant 0 lt numSlackVars
numSlackVars lt rowsinvariant numInitialVars
numSlackVars 1 columnsinvariant rhsColumn
columns - 1invariant dims.Count
numInitialVarsinvariant basisColumns.Length
rowsinvariant inBasis.Length numInitialVars
numSlackVars
31Spec demo
32Spec verifier architecture
Spec
Spec compiler
MSIL (bytecode)
Boogie
Spec static program verifier, aka
translator
inference engine
Boogie PL
V.C. generator
verification condition
automatictheorem prover
correct or list of errors
33Analyzing verification conditions
- Automatic theorem prover
- can be hidden from programmer
- generates counterexamples
- Interactive theorem prover
- requires gurus
- not limited by built-in decision procedures
34Generating verification conditions
Weakest preconditions
- int AbsX(Robot c) requires c ? null ensures 0
result if (0 c.x) a c.x else
a -c.x return a
c ? null ? c ? null ? (0 sel(c,x) ? c ? null
? 0 sel(c,x)) ? ((0 sel(c,x)) ? c ? null ?
0 -sel(c,x))
c ? null ? (0 sel(c,x) ? c ? null ? 0
sel(c,x)) ?((0 sel(c,x)) ? c ? null ? 0
-sel(c,x))
c ? null ? 0 sel(c,x)
c ? null ? 0 -sel(c,x)
0 a
0 result
35Whats in a language
- the programming languageis the software
engineer'sprimary thinking and working tool
36Designing more rigor into the language
Examples
- Type system
- impose coarse-grained restrictions
- easy to understand and use
- sound efficient checking
- General specifications
- enforce by mix of dynamic and static checking
- dont worry about completeness or decidability
- Develop good defaults
non-null types
requires Premodifies Frameensures Post
requires this.inv Validmodifies
this.ensures true
37Enforcing specifications
- Run-time checking
- may leave out expensive checks, if not required
for soundness - example modifies clauses
- Static verification
- requires more effort from the user
- example modifies clauses
- modular checking a necessity
type checking
static verification
run-time checks
degree of checking,effort
38Migration problems
- To the new language
- how does the language compare to existing ones?
- From (!) the new language
- development organizations may have process
requirements
contracts everywhere
C
into the future
39Conclusions
- Trend toward more rigorous languages and checking
- Desire to contribute customized specifications
- Tool support is crucial
- Despite significant advances in the use of static
analyses, we need more experience before wed
expect users to take on more detailed
verification tasks - Some areas where more research will help
- language design
- program semantics
- specification techniques
- inference algorithms
- decision procedures
- methodology
http//research.microsoft.com/specsharp
download Specfrom here