260 likes | 332 Views
Evaluating and Tuning a Static Analysis to Find Null Pointer Bugs. David Hovemeyer, Jaime Spacco, and William Pugh. Presented by Nathaniel Ayewah CMSC838P 11/16/2006. Why Simple. Programmers make simple mistakes // org.eclipse.jdt.internal.ui.compare.JavaStructureDiffViewer
E N D
Evaluating and Tuning a Static Analysis to Find Null Pointer Bugs David Hovemeyer, Jaime Spacco, and William Pugh Presented by Nathaniel Ayewah CMSC838P 11/16/2006
Why Simple • Programmers make simple mistakes // org.eclipse.jdt.internal.ui.compare.JavaStructureDiffViewer Control c = getControl(); if (c == null && c.isDisposed()) return; • Low False Positive Rate • Cannot find all bugs
Findbugs INPUT PROCESSING OUTPUT • Set of “.class” files containing byte-code • Configurations • Bug Pattern Code • Source Line Number • Descriptive Message Detectors
Findbugs Detectors PROCESSING • Independent of each other • May share some resources • GOAL: Low false positives • Each detector is driven by a set of heuristics Know Your Bug Patterns
Output HIGH SEVERE RISK OF PROGRAM FAILURE MEDIUM ELEVATED RISK OF PROGRAM FAILURE LOW LOW RISK OF PROGRAM FAILURE Source: US Department of Program Security
Findbugs Detectors PROCESSING Null Pointer Analysis
Null Pointer Analysis PROCESSING • Forward intra-procedural • Build Control Flow graph for each method Slot Method parmeter, local variable, or stack operand Null NonNull Data-flow Frame
Simple Analysis Detector foo = null; foo.execute(); HIGH SEVERE RISK OF PROGRAM FAILURE Dereferencing Null Detector foo = new Detector(…); foo.execute(); Dereferencing NonNull
If only it were that simple… • Is a method’s parameter null? void foo(Object obj) { int x = obj.hashcode(); … } • Infeasible Paths
Infeasible Paths • Guard indirectly connected to null check boolean b; if (p != null) b = true; else b = false; if (b) p.f()
Infeasible Paths • Assertions p = null; ... // throws exception if p null: checkAssertion(p != null); p.f(); // safe
Infeasible Paths • Checked Exceptions that are never thrown Foo dup = null; try { dup = super.clone(); } catch (CloneNotSupportedException e) { // Can’t happen } dup.contents = ...
Solution • Null and NonNull are not enough Checked NonNull No Kaboom NonNull if (b) { A } else { B } C ? NonNull Null-E NCP Null NSP-E NSP
Solution • Dereferencing a variable that has value Null, NSP, … MEDIUM ELEVATED RISK OF PROGRAM FAILURE Null-E … HIGH SEVERE RISK OF PROGRAM FAILURE LOW LOW RISK OF PROGRAM FAILURE Null NSP-E NSP MEDIUM ELEVATED RISK OF PROGRAM FAILURE
Solution • Choosing a value for a variable after each statement: Statement Value of p p = null Null p = this NonNull p = new ... NonNull p = "string" NonNull p = Foo.class NonNull p = q.x NCP p = a[i] NCP p = f() NCP
Solution: Infeasible Paths p = null; Null Null p = new … NonNull Null NSP NCP NCP
Solution: Infeasible Paths Null or NSP checkAssertion(p != null) NCP p.f()
Solution: Infeasible Paths try { } Null NSP catch(Exception e) { } Null-E NSP-E
Comparing a Value to null foo.execute(); if (foo != null) { ... } Comparing No-Kaboom to null HIGH SEVERE RISK OF PROGRAM FAILURE
Comparing a value to null Detector foo = null; if (foo != null) { foo.execute(); } MEDIUM ELEVATED RISK OF PROGRAM FAILURE Comparing Null to null R.I.P if (foo != null) { ... if (foo == null) { foo = new ... } } Comparing Checked NonNull to null MEDIUM ELEVATED RISK OF PROGRAM FAILURE R.I.P
Other Solutions • Check for methods that unconditionally dereference parameters • Annotations • @NotNull: parameter/return value must not be null • @CheckForNull: check the parameter/return value before dereferencing it
Experiments: Student Code • With Annotations
Experiments: Student Code • Without Annotations
Experiments: Production Code • Cannot calc. false negatives! Eclipse 3.0.1
Conclusion • More inter-procedural techniques could find more bugs • But often finding simple bugs with low FP rate is effective