Annotation-Assisted Lightweight Static Checking David Evans

advertisement
Annotation-Assisted
Lightweight Static
Checking
David Evans
evans@cs.virginia.edu
http://lclint.cs.virginia.edu
LCLint
Collaborators: John Knight, David Larochelle
University of Virginia
Department of Computer Science
A Gross Oversimplification
all
Bugs Detected
Formal Verifiers
Compilers
none
Low
4 June 2000
David Evans
Effort Required
Unfathomable
2
4 June 2000
David Evans
3
Requirements
• No interaction required – as easy to use
as a compiler
• Fast checking – as fast as a compiler
• Gradual Learning/Effort Curve
– Little needed to start
– Clear payoff relative to user effort
4 June 2000
David Evans
4
Approach
• Programmers add annotations (formal
specifications)
– Simple and precise
– Describe programmers intent:
• Types, memory management, data hiding,
aliasing, modification, null-ity, etc.
• LCLint detects inconsistencies between
annotations and code
– Simple (fast!) dataflow analyses
4 June 2000
David Evans
5
Sample Annotation: only
extern only char *gptr;
extern only out null void *malloc (int);
•
•
•
•
Reference (return value) owns storage
No other persistent (non-local) references to it
Implies obligation to transfer ownership
Transfer ownership by:
– Assigning it to an external only reference
– Return it as an only result
– Pass it as an only parameter: e.g.,
extern void free (only void *);
4 June 2000
David Evans
6
Example
extern only null void *malloc (int); in library
1 int dummy (void) {
2
int *ip= (int *) malloc (sizeof (int));
3
*ip = 3;
4
return *ip;
5 }
LCLint output:
dummy.c:3:4: Dereference of possibly null pointer ip: *ip
dummy.c:2:13: Storage ip may become null
dummy.c:4:14: Fresh storage ip not released before return
dummy.c:2:43: Fresh storage ip allocated
4 June 2000
David Evans
7
Checking Examples
• Encapsulation – abstract types (rep
exposure), global variables,
documented modifications
• Memory management – leaks, dead
references
• De-referencing null pointers, dangerous
aliasing, undefined behavior (order of
modifications, etc.)
4 June 2000
David Evans
8
Unsoundness &
Incompleteness are Good!
• Okay to miss errors
– Report as many as possible
• Okay to issue false warnings
– But don’t annoy the user to too many
– Make it easy to configure checking and
override warnings
• Design tradeoff – do more ambitious
checking the best you can
4 June 2000
David Evans
9
LCLint Status
• Public distribution since 1993
• Effective checking >100K line programs
(checks about 1K lines per second)
– Detects lots of real bugs in real programs
(including itself, of course)
– Over 1000 users
• More information: lclint.cs.virginia.edu
PLDI ’96, FSE’94
4 June 2000
David Evans
10
Where do we go from here?
• Extensible Checking
– Allow users to define new annotations and
associated checking
• Integrate run-time checking
– Combine static and run-time checking to enable
additional checking and completeness guarantees
• Generalize framework
– Support static checking for multiple source
languages in a principled way
4 June 2000
David Evans
11
Extensible Checking
• LCLint engine provides analysis core
– Events associated with code points
– Control flow analysis, alias analysis
• User (library) defines checking rules
– Introduces state associated with types of objects
(e.g., references, numeric values)
– Defines annotations for initializing and
constraining that state
– Defines checking rules associated with code
events
4 June 2000
David Evans
12
Example: Nullity
state nullity {
applies to reference
oneof { notnull, maybenull, isnull }
default maybenull
merge {
notnull + (maybenull | isnull) = maybenull
maybenull + * = maybenull
isnull + (maybenull | notnull) = maybenull
}
guard {
!= NULL => notnull
== NULL => isnull
}
}
4 June 2000
David Evans
13
Nullity Checks
checks (reference x) nullity {
transfer (notnull, { notnull, maybenull })
transfer (maybenull, maybenull)
transfer (isnull, { isnull, maybenull });
*x requires notnull
}
annotation null : reference declaration
requires state nullity
nullity = maybenull;
annotation notnull : reference declaration
requires state nullity
nullity = notnull;
4 June 2000
David Evans
14
Example: Sharing
state sharing {
applies to reference
oneof { only, temp, shared, dead }
default { result, global, field } only
parameter temp
}
annotation only : reference x
{ x.sharing = only; }
annotation temp : reference x
{ x.sharing = temp; }
4 June 2000
David Evans
15
Sharing Checks
checks (reference x) {
must transfer
transfer (only, only) becomes dead
transfer (temp, only)
use x requires not dead
}
4 June 2000
David Evans
16
Open Questions
• What are the primitives?
• What are the limits on checking?
– Without sacrificing static and efficient
requirements
• Can decent messages be generated
automatically from checking definitions?
• Is this framework sufficiently powerful to
describe a useful class of checks?
• Is this framework sufficiently accessible to
allow programmers to define applicationspecific checks?
4 June 2000
David Evans
17
Test Cases
• Built-in LCLint annotations and checks
• Buffer Overflows [David Larochelle]
– Adapted from [Wagner00]
– Depends on numerical range analysis
• Can this be defined or must it be a primitive?
• Information flow
– Based on JFlow [Myers99]
– Need to provide parameterized annotations
– Support for polymorphism
• Can this be defined or must to be added to engine?
4 June 2000
David Evans
18
Summary
• A little redundancy goes a long way
– Don’t need a full specification to do useful
checking
– Gradually add more redundancy to get
better checking
• Lots of opportunity for user-defined
checking
– But many open questions to answer
4 June 2000
David Evans
19
Credits
• LCLint
David Larochelle
LCL: Yang Meng Tan, John Guttag,
Jim Horning
• Funding
DARPA, NSF, ONR, NASA
4 June 2000
David Evans
20
State, Annotations and Checking
• A large class of useful checking involves:
– Associating state with references at execution
points
– Providing type-judgment rules for the new state
– Providing state transition rules
• Can we define this class?
• Can we describe new annotations and
checks in a way the is accessible to normal
programmers?
– Don’t want rules for every grammar production
4 June 2000
David Evans
21
Concrete Example: Buffer
Overflow Errors
• [credits]
• State:
reference {
bool nullterminated;
int allocated;
int
4 June 2000
David Evans
22
Download