Upload
sierra-marsh
View
216
Download
0
Tags:
Embed Size (px)
Citation preview
Advanced programming tools at Microsoft
K. Rustan M. LeinoMicrosoft Research, Redmond, WA, USA
16 May 2005Distinguished lecture, York UniversityToronto, ON, Canada
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 protocolsmark-ups
pre- and postconditions, andobject invariants
More powerful techniques—a selection
0. PREfix1. SLAM2. SpecStrings3. Spec#
0. PREfix
• 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
[Bush, Pincus, Sielaff, et al.]
PREfix example
int abs(int x) {int y;if (0 <= x) {
y = x;}return y;
}possible use of
uninitialized variable
PREfix 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
The PREfast revolution
• 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
[Weise, et al.]
On the road to embracing static analysis:
PREfix milestonePREfix and PREfast have openedeyes of developers and managementto power of compile-time checking
1. Niche: device drivers
• bugs can have severe effects• relatively small code base (usually ≤
50 KLOC)• crash-freedom specified by finite-state
API protocols• correctness mostly
depends on flow ofcontrol, not data
Acquire()
Acquire()Release()
Release()
SLAM
• Software model checking– predicate abstraction– model checking (state exploration)– counterexample-driven predicate
refinement
[Ball, Rajamani, et al.]
error message
Predicate abstraction and refinement
C program
predicates
boolean program
modelchecker
correct
concrete trace
feasible?
abstract trace
no yes
predicateabstraction
predicaterefinement
SLAM example
do {KeAcquireSpinLock();
nPacketsOld = nPackets;
if (request) {request = request->Next;KeReleaseSpinLock();nPackets++;
}} while (nPackets != nPacketsOld);
KeReleaseSpinLock();
Acquire()
Acquire()Release()
Release()
SLAM example
do {assert ¬P; P := true; // KeAcquireSpinLock();
if ( * ) {
assert P; P := false; // KeReleaseSpinLock();
}} while ( * );
assert P; P := false; // KeReleaseSpinLock();
Predicates:
• P: spin lock held
SLAM example
do {assert ¬P; P := true;
if ( * ) {
assert P; P := false;
}} while ( * );
assert P; P := false;
error path in abstract program
Predicates:
• P: spin lock held
SLAM example
do {KeAcquireSpinLock();
nPacketsOld = nPackets;
if (request) {request = request->Next;KeReleaseSpinLock();nPackets++;
}} while (nPackets != nPacketsOld);
KeReleaseSpinLock();
error path in abstract program
infeasible path in concrete program
Predicates:
• P: spin lock held
SLAM example
do {KeAcquireSpinLock();
nPacketsOld = nPackets;
if (request) {request = request->Next;KeReleaseSpinLock();nPackets++;
}} while (nPackets != nPacketsOld);
KeReleaseSpinLock();
error path in abstract program
Predicates:
• P: spin lock held
• Q: nPackets == nPacketsOld
infeasible path in concrete program
SLAM example
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;
Predicates:
• P: spin lock held
• Q: nPackets == nPacketsOld
no error path in abstract program;hence, concrete program is correct
SLAM 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
On the road to embracing static analysis:
SLAM milestoneSLAM showcases specifications and powerful checking
2. SpecStrings
• 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
[Das, Fähndrich, et al.]
SpecString example
void * memcpy(pre notnullpre writableTo(pre byteCount(num)) post readableTo(pre byteCount(num)) void * dest,
pre notnull pre readableTo(pre byteCount(num))void * src,
size_t num);
SpecStrings at Microsoft
• emphasizes importance of interfaces• better documentation• improves checking
– fewer spurious warnings– can detect errors from violations of
stated intent
On the road to embracing static analysis:
SpecStrings milestoneWith SpecStrings, developers become used to source-code annotations that go beyond what compiler requires
3. 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
Spec#• 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
C#contracts
everywhere
type checking
static verification
into the future
run-time checks
degree of checking,effort
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.
Exceptions
Exception 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.
Specifications today
Spec# specificationsPrecondition• 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 || (startIndex == 0 && charCount == 0); requires 0 <= startIndex && 0 <= charCount; requires startIndex + charCount <= value.Length;
ensures result == this;
Object invariantsreadonly int rows;readonly int columns;readonly double[,] m;
readonly int numInitialVars;readonly int numSlackVars;readonly int rhsColumn;
readonly ArrayList<object> dims;readonly int[] basisColumns;readonly int[] inBasis;bool constructionDone = false;
invariant rows == m.GetLength(0);invariant 1 <= columns && columns == m.GetLength(1);invariant 0 <= numInitialVars;invariant 0 <= numSlackVars && numSlackVars <= rows;invariant numInitialVars + numSlackVars + 1 == columns;invariant rhsColumn == columns - 1;invariant dims.Count == numInitialVars;invariant basisColumns.Length == rows;invariant inBasis.Length == numInitialVars + numSlackVars;
Spec# demo
Spec# verifier architecture
V.C. generator
automatictheorem prover
verification condition
Spec#
“correct” or list of errors
Spec# compiler
MSIL (“bytecode”)
translator
Boogie PL
inference engine
Spec# static program verifier, akaBoogi
e
Analyzing verification conditions• Automatic theorem prover
– can be hidden from programmer– generates counterexamples
• Interactive theorem prover– requires gurus– not limited by built-in decision
procedures
Generating verification conditions
int AbsX(Robot c)requires c ≠ null;ensures 0 ≤ result;
{if (0 ≤ c.x) {
a := c.x;} else {
a := −c.x;}return a;
}
Weakest preconditions
0 ≤ result
0 ≤ a
c ≠ null 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 c ≠ null (0 ≤ sel(c,x) c ≠ null 0 ≤ sel(c,x)) (¬(0 ≤ sel(c,x)) c ≠ null 0 ≤ −sel(c,x))
the programming languageis the software engineer'sprimary thinking and working tool
What’s in a language
Designing more rigor into the language
• Type system– impose coarse-grained restrictions– easy to understand and use– sound efficient checking
• General specifications– enforce by mix of dynamic and static
checking– don’t worry about completeness or
decidability
• Develop good defaults
non-null types
requires Pre;modifies Frame;ensures Post;
Examples
requires this.inv = Valid;modifies this.*;ensures true;
Enforcing 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
Migration problems
• To the new language– how does the language compare to
existing ones?
• From (!) the new language– development organizations may have
process requirements
C#contracts
everywhere
into the future
download Spec#from here
Conclusions• 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 we’d 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