william pugh univ. of maryland findbugs · • common idiom for thread safe classes is to...

61
Squashing Bugs with Static Analysis William Pugh Univ. of Maryland http://www.cs.umd.edu/~pugh / http://findbugs.sourceforge.net / SD Best Practices, 2006 FindBugs

Upload: others

Post on 26-Apr-2020

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Squashing Bugs with Static Analysis

William Pugh

Univ. of Maryland

http://www.cs.umd.edu/~pugh/

http://findbugs.sourceforge.net/

SD Best Practices, 2006

FindBugs™

Page 2: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

FindBugs

• Open source static analysis tool for finding defects in Java programs

• Analyzes classfiles

• Generates XML or text output

• can run in Netbeans/Swing/Eclipse/Ant/SCA

• Total downloads from SourceForge: 274,291+

2

Page 3: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

What is FindBugs?• Static analysis tool to find defects in Java code

• not a style checker

• Can find hundreds of defects in each of large apps such as Bea WebLogic, IBM Websphere, Sun's JDK

• real defects, stuff that should be fixed

• hundreds is conservative, probably thousands

• Doesn’t focus on security

• lower tolerance for false positives3

Page 4: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Common Wisdom about Bugs

• Programmers are smart

• Smart people don’t make dumb mistakes

• We have good techniques (e.g., unit testing, pair programming, code inspections) for finding bugs early

• So, bugs remaining in production code must be subtle, and require sophisticated techniques to find

4

Page 5: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Would You Write Code Like This?

if (in == null)

try {

in.close();

...

• Oops

• This code is from Eclipse (versions 3.0 - 3.2)

• You may be surprised what is lurking in your code

5

Page 6: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

6

Why Do Bugs Occur?

• Nobody is perfect

• Common types of errors:

• Misunderstood language features, API methods

• Typos (using wrong boolean operator, forgetting parentheses or brackets, etc.)

• Misunderstood class or method invariants

• Everyone makes syntax errors, but the compiler catches them

• What about bugs one step removed from a syntax error?

Page 7: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Bug Patterns

Page 8: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Infinite recursive loop• Student came to office hours, was having trouble

with his constructor:

/** Construct a WebSpider */

public WebSpider() { WebSpider w = new WebSpider();

}

• A second student had the same bug

• Wrote a detector, found 3 other students with same bug

8

Page 9: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Double check against JDK

• Found 4 infinite recursive loops

• Including one written by Joshua Bloch

public String foundType() {

return this.foundType();

}

• Smart people make dumb mistakes

• Embrace and fix your dumb mistakes

9

Page 10: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

0

2

4

6

8

10

12

14

16

18

20

jdk1.0.2

j2sdk1_3_1_03

j2sdk1.4.0-b72

j2sdk1.4.0-b82

j2sdk1.4.1-b06

j2sdk1.4.1-b14

j2sdk1.4.2-b06

j2sdk1.4.2-b14

j2sdk1.4.2-b20

j2sdk1.4.2_04

j2sdk1.5.0-b12

j2sdk1.5.0-b20

j2sdk1.5.0-b28

j2sdk1.5.0-b36

j2sdk1.5.0-b44

j2sdk1.5.0-b51

j2sdk1.5.0-b58

j2sdk1.5.0-b64

jdk1.5.0_04

jdk1.6.0-b13

jdk1.6.0-b17

jdk1.6.0-b26

jdk1.6.0-b30

jdk1.6.0-b34

jdk1.6.0-b38

jdk1.6.0-b42

jdk1.6.0-b46

jdk1.6.0-b50

jdk1.6.0-b54

jdk1.6.0-b58

jdk1.6.0-b62

jdk1.6.0-b66

jdk1.6.0-b70

jdk1.6.0-b74

jdk1.6.0-b78

jdk1.6.0-b82

active dead

I inform Sun of infinite recursive

loops in their code

JDK build

Infinite Recursive Loops: Sun JDK history

Page 11: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Duration of infinite recursive loop bugs in JDK

Page 12: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

12

Hashcode/Equals

• Equal objects must have equal hash codes

• Programmers sometimes override equals() but not hashCode()

• Or, override hashCode() but not equals()

• Objects violating the contract won’t work in hash tables, maps, sets

• Examples (53 bugs in 1.6.0-b29)

• javax.management.Attribute

• java.awt.geom.Area

Page 13: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Fixing hashCode

• What if you want to define equals, but don't think your objects will ever get put into a HashTable?

• Suggestion:

public int hashCode() { assert false : "hashCode method not designed"; return 42; }

13

Page 14: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

14

Null Pointer Dereference

• Dereferencing a null value results in NullPointerException

• Warn if there is a statement or branch that if executed, guarantees a NPE

• Example:// Eclipse 3.0.0M8

Control c = getControl();

if (c == null && c.isDisposed())

return;

Page 15: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

15

More Null Pointer Dereferences

// Eclipse 3.0.0M8

String sig = type.getSignature();

if (sig != null || sig.length() == 1) {

return sig;

}

// JDK 1.5 build 42

if (name != null || name.length > 0) {

Page 16: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

16

More Null Pointer Dereferences

javax.security.auth.kerberos.KerberosTicket, 1.5b42

// flags is a parameter

// this.flags is a field

if (flags != null) {

if (flags.length >= NUM_FLAGS)

this.flags = ...

else

this.flags = ...

} else

this.flags = ...

if (flags[RENEWABLE_TICKET_FLAG]) {

Page 17: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

17

Redundant Null Comparison

• Comparing a reference to null when it is definitely null or definitely non-null

• Not harmful per se, but often indicates an inconsistency that might be a bug

• Example (JBoss 4.0.0DR3):

protected Node findNode(Fqn fqn, ...) {

int treeNodeSize = fqn.size();

...

if (fqn == null) return null;

Page 18: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

How should we fix this bug?

if (name != null || name.length > 0)

• Should we just change it to

if (name != null && name.length > 0)

• Will that fix it?

• We have no idea. Obviously, we’ve never tested the situation when name is null.

• Try to write a test case first, then apply the obvious fix

18

Page 19: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Bad Binary operations

if ((f.getStyle () & Font.BOLD) == 1) { sbuf.append ("<b>"); isBold = true; }

if ((f.getStyle () & Font.ITALIC) == 1) { sbuf.append ("<i>"); isItalic = true; }

19

Page 20: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Doomed Equals

public static final ASDDVersion getASDDVersion(BigDecimal version) { if(SUN_APPSERVER_7_0.toString() .equals(version)) return SUN_APPSERVER_7_0;

20

Page 21: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Unintended regular expression

String[] valueSegments = value.split("."); // NOI18N

21

Page 22: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Field Self Assignment

public TagHelpItem(String name, String file, String startText, int startOffset, String endText, int endOffset, String textBefore, String textAfter){ this.name = name; this.file = file; this.startText = startText; this.startTextOffset = startTextOffset; this.endText = endText; this.endTextOffset = endTextOffset; this.textBefore = textBefore; this.textAfter = textAfter; this.identical = null; }

22

Page 23: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

23

Bad Naming

package org.eclipse.jface.dialogs;

public abstract class Dialog extends Window {

protected Button getOKButton() {

return getButton(IDialogConstants.OK_ID);

};}

public class InputDialog extends Dialog {

protected Button getOkButton() {

return okButton;

};

}Wrong capitalization

Page 24: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

24

Confusing/bad naming

• Methods with identical names and signatures– but different capitalization of names– could mean you don’t override method in

superclass– confusing in general

• Method name same as class name– gets confused with constructor

Page 25: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Bad naming in BCEL(shipped in jdk1.6.0-b29)

/** @return a hash code value *for the object.

*/

public int hashcode() { return basic_type.hashCode() ^ dimensions; }

25

Page 26: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

26

Ignored return values

• Lots of methods for which return value always should be checked– E.g., operations on immutable objects

// Eclipse 3.0.0M8String name= workingCopy.getName();name.replace(’/’, ’.’);

Page 27: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Ignored Exception Creation/** * javax.management.ObjectInstance * reference impl., version 1.2.1 **/ public ObjectInstance(ObjectName objectName, String className) { if (objectName.isPattern()) { new RuntimeOperationsException( new IllegalArgumentException( "Invalid name->"+ objectName.toString())); } this.name = objectName; this.className = className; }

27

Page 28: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

28

Inconsistent Synchronization

• Common idiom for thread safe classes is to synchronize on the receiver object (“this”)

• We look for field accesses– Find classes where lock on “this” is sometimes,

but not always, held– Unsynchronized accesses, if reachable from

multiple threads, constitute a race condition

Page 29: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

29

Inconsistent Synchronization Example

• GNU Classpath 0.08, java.util.Vector

public int lastIndexOf(Object elem){ return lastIndexOf(elem, elementCount – 1);}

public synchronized int lastIndexOf( Object e, int index){ ...}

Page 30: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

30

Unconditional Wait

• Before waiting on a monitor, the condition should be almost always be checked– Waiting unconditionally almost always a bug– If condition checked without lock held, could miss the

notification

• Example (JBoss 4.0.0DR3):if (!enabled) { try { log.debug(...); synchronized (lock) { lock.wait(); }

condition can become true after it is checked

but before the wait occurs

Page 31: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Bug Categories• Correctness• Bad Practice

– equals without hashCode, bad serialization, comparing Strings with ==, equals should handle null argument

• Dodgy– Dead store to local variable, load of known null

value, overbroad catch

• Performance• Multithreaded correctness• Malicious code vulnerability

31

Page 32: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Demo

• Live code review

• Available as Java Webstart from

• http://findbugs.sourceforge.net/demo.html

32

Page 33: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Warning Density

Page 34: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Warning density• Density of high and medium priority correctness

warnings

Warnings/KNCSS Software0.1 SleepyCat DB

0.3 Eclipse 3.2

0.6 JDK 1.5.0_03

0.6 JDK 1.6.0 b51

0.9 IBM WebSphere 6.0.334

Page 35: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Some new-ish featuressome have been around for a while but aren’t well

known (or well documented)

Page 36: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Annotations for Software Defect Detection

• Allow you to provide lightweight specifications through Java 5.0 annotations

• Examples

• @NonNull

• @CheckForNull

• @CheckReturnValue

36

Page 37: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

JSR-305

• JSR and expert group as formed to develop standard annotations that can be used by multiple tools

• IntelliJ also has annotations for nullness, but they aren’t the same

• JSR will develop standard annotations in the javax namespace, with agreements as to their semantics

• Unofficial output: annotated versions of standard libraries

37

Page 38: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Computing bug history

• Keeps track of when bug are introduced, when they are resolved

• Historical bug data records all bugs reported for any build

• Can see when bugs were introduced and removed

• For example, can report all bugs introduced in the past 3 months

38

Page 39: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

User bug designations annotations

• Our framework and new GUI allow users to designate specific bugs as “Must Fix” or “Not a Bug”

• can also provide free text annotation

• When matching previous analysis results with new analysis results, bugs are matched and annotations carried forward

39

Page 40: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

New GUI

• Provides user designation and annotation support

• Highlights multiple source lines

• Use dragging to reorganize JTree

40

Page 41: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Command line tools

Page 42: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Command line tools

• We’ve got a lot of command line tools

• some ant tasks, need to add more

• but all the command lines tools can be invoked from within ant

• We need to build a bigger, better tool chain

• we’re open source, we welcome contributions

• Maven (contributed), Cruise control (?), ...

42

Page 43: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

XML analysis results

• We use XML as the standard output from our analysis engine

• XML analysis results can be filtered, processed, displayed in the GUI, annotated, converted to text or HTML

• XML can be plain, or with messages

• with text/messages provides all the text to allow you to convert the XML into meaningful HTML without further FindBugs involvement

43

Page 44: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

findbugs

• findbugs -textui -xml rt.jar >rt.xml

• run findbugs

• using the test user interface, rather than the GUI

• generate XML output, rather than one bug/line

• also have emacs output mode

• analyze all the classes in rt.jar, write the output to rt.xml

44

Page 45: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

filterBugs

• filterBugs -priority H -category C rt.xml hc.xml

• Read the bugs in rt.xml, filter out just the high priority correctness bugs, and write them to hc.xml

45

Page 46: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

convertXmlToText

• convertXmlToText hc.xml

• convert to simple one bug/line format

• convertXmlToText -html:fancy.xsl

• convert to html using fancy.xsl style sheet

46

Page 47: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

listBugDatabaseInfo& setBugDatabaseInfo

• Set information about the analysis

• -name name this analysis/version

• -time Give the timestamp for this analysis

• -addSource add a source directory

• -findSource find and add all relevant source directories

47

Page 48: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

unionBugs

• combine results from analyzing disjoint classes into a single analysis file

• don’t use this if the analysis files contain overlapping results

48

Page 49: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

computeBugHistory

• computeBugHistory -output db.xml old.xml new.xml

• combine the analysis results in old.xml and new.xml

• write a historical analysis to db.xml

• old.xml can be a historical analysis

49

Page 50: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

matching old bugs with new bugs

• We do a number of clever things (or things we think are clever) to match warnings from an old analysis with warnings in a new analysis

• Line numbers don’t matter

• We err on overmatching

• if you modify a method, fixing one null pointer bug, and introducing another in the same method, we may think the bug hasn’t changed

50

Page 51: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

mineBugHistory

• mineBugHistory -formatDates -noTabs db.xml

• produce a tabular listing of the number of bugs introduced and eliminated in each build/version in a historical analysis

51

Page 52: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Historical bug databases

• Each historical bug database records a sequence of versions/builds/analysis results

• Each analysis result has a name, a date and a sequence number (starting at 0)

52

Page 53: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Combing back to filterBugs

• filterBugs has lots of options

filterBugs -first 1 db.xml | convertXmlToText

• filter out just the warnings that first appeared in sequence # 1 (the second analysis results), and convert the results to text

53

Page 54: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Importing bugs into your own bug databases

• if you want to bring our results into a database

• generate xml with messages

• use instance-hash

• designed to be unique per bug, and match bugs across versions

• Not as clever as the approach we use when matching XML, but still clever

54

Page 55: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

FindBugs Best Practices

Page 56: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

What to look at

• First review high and medium priority correctness

• Low priority warnings can be of questionable value

• FindBugs doesn’t report these by default

• more there for us to work to improve our accuracy, and figure out how to raise the priority of the important ones and drop the unimportant ones

• Other categories worth examining in a code review, but insisting that they all be reviewed immediately will make people unhappy

56

Page 57: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Compile with debugging information

• We produce more accurate results and more meaningful messages if the classfiles contain both line numbers and local variable names

• use javac -g

• If you are computing historical information, be consistent with whether you generate debugging information

57

Page 58: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

FindBugs plugins

• Carefully consider and review open source FindBugs plugins

• Others have written plugins, some of which generate a lot more false positives or give bad advice

• You can write your own plugins

• particularly great if you have bugs that are specific to your project

58

Page 59: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Incremental analysis and/or marking

• For sustainable use, you need to have some way to deal with false positives

• mark in database

• Only review new warnings

• Both of these require matching warnings from one analysis with results from a previous analysis

59

Page 60: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Developers like incremental analysis

• Developers don’t like to be asked to scrub a million line code base and review 1000 warnings

• But they don’t mind (as much) if you ask them to review a new warning introduced by a change they just made

• false positive rate still matters

60

Page 61: William Pugh Univ. of Maryland FindBugs · • Common idiom for thread safe classes is to synchronize on the receiver object (“this”) • We look for field accesses – Find

Questions?