1<br />FindBugs™ - Find Bugs in Java Programs<br />Defective Java Code<br />Learning from mistakes<br />Carol McDonald<br />
2<br />What is FindBugs?<br /><ul><li>Static analysis tool
Looks for defects based on bug patterns
Bug patterns come from real bugs
bug patterns are grouped into categories:
correctness, bad practice, performance…
assigned a priority: high, medium or low.
High-Medium priority have low false positive rates
http://findbugs.sourceforge.net/</li></li></ul><li>© Availity, LLC | All rights reserved.	<br />3<br />Bug Patterns<br /><...
a read or write on a null pointer
typos
Methods whose return value should not be ignored
Also specific bug patterns:
Every Programming Puzzler
Eclipse documented bug fixes
Every chapter in Effective Java
Many postings to http://thedailywtf.com/</li></ul>3<br />
© Availity, LLC | All rights reserved.	<br />4<br />BugPatterns: http://thedailywtf.com/<br />4<br />
© Availity, LLC | All rights reserved.	<br />5<br />Some<br />bug<br />Patterns:<br />
© Availity, LLC | All rights reserved.	<br />6<br />Some<br />bug<br />Patterns:<br />
7<br />Misconceptions about Bugs<br /><ul><li>Programmers are smart
Smart people don’t make dumb mistakes
WRONG!
Smart people make dumb mistakes
Common errors:
wrong boolean operator, forgetting parentheses, etc.
Misunderstood class or method  !</li></li></ul><li>8<br />Can you find the Bug? <br />if (listeners == null)<br />listener...
9<br />Who uses FindBugs? <br /><ul><li>Developed from Research at University of Maryland
Google, Ebay, Sun, Wells Fargo…
Bill Pugh spent a year sabbatical at Google  working Findbugs  into their development process
Google runs FindBugs over all Java code
1800s issues identified, > 600 fixed.
Ebay found 2 developers reviewing  Findbugs  was 10 times more effective than 2 testers</li></li></ul><li>10<br />Some Bug...
Concurrency
Performance</li></ul>• Security defect<br />
11<br />Can you find the Bug? <br />public String sendMessage (User user, String body, Date time) {<br />    return sendMe...
12<br />Infinite recursive loopHigh priority correctness<br />public String sendMessage (User user, String body, Date time...
13<br />Can you find the Bug? <br />public String foundType() {<br />   return this.foundType();<br />}<br />
14<br />Infinite recursive loop<br />public String foundType() {<br />   return this.foundType();<br />}<br />// should be...
15<br />Can you find the Bug? <br />if (name != null || name.length > 0)<br />
16<br />Can you find the Bug? <br />if (name != null || name.length > 0)<br />if (name != null &&name.length > 0)<br />Fou...
17<br />Can you find the Bug? <br />if (part == null | part.equals(""))<br />
18<br />Can you find the Bug? <br />if (part == null | part.equals(""))<br />if (part == null ||part.equals(""))<br />Foun...
19<br />Null Pointer Bugs found in com.sun….<br />if (name != null || name.length > 0)<br />if (part == null | part.equals...
© Availity, LLC | All rights reserved.	<br />20<br />Can you find the Bug? <br />//BoundedThreadPool<br />private final St...
© Availity, LLC | All rights reserved.	<br />21<br />found in Jetty….<br />//BoundedThreadPoolprivate final String _lock =...
22<br />Problem?<br />public final WritableRaster filter( Raster src, 	WritableRasterdst) {<br />intdstLength = dst.getNum...
23<br />Redundant Check for Null<br />Is it a bug or a redundant check?<br />public final WritableRaster filter( Raster sr...
24<br />Can you find the Bug? <br />if (adapters == null && adapters.length == 0)<br />	return;<br />Eclipse, 3.5RC3<br />...
Won’t return if length is 0, error harder to find</li></li></ul><li>25<br />Problem?<br />// com.sun.xml.internal.txw2.out...
26<br />Bad Method Call<br />// com.sun.xml.internal.txw2.output.XMLWriter<br />try { ... }<br />catch (IOException e) {<b...
27<br />Problem?<br />public static String getNameById(String userId) {<br />    String str = userId;<br />    ...<br />st...
Upcoming SlideShare
Loading in...5
×

Finding bugs that matter with Findbugs

2,288

Published on

Published in: Technology
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,288
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
87
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Transcript of "Finding bugs that matter with Findbugs"

  1. 1. 1<br />FindBugs™ - Find Bugs in Java Programs<br />Defective Java Code<br />Learning from mistakes<br />Carol McDonald<br />
  2. 2. 2<br />What is FindBugs?<br /><ul><li>Static analysis tool
  3. 3. Looks for defects based on bug patterns
  4. 4. Bug patterns come from real bugs
  5. 5. bug patterns are grouped into categories:
  6. 6. correctness, bad practice, performance…
  7. 7. assigned a priority: high, medium or low.
  8. 8. High-Medium priority have low false positive rates
  9. 9. http://findbugs.sourceforge.net/</li></li></ul><li>© Availity, LLC | All rights reserved. <br />3<br />Bug Patterns<br /><ul><li>broad and common patterns:
  10. 10. a read or write on a null pointer
  11. 11. typos
  12. 12. Methods whose return value should not be ignored
  13. 13. Also specific bug patterns:
  14. 14. Every Programming Puzzler
  15. 15. Eclipse documented bug fixes
  16. 16. Every chapter in Effective Java
  17. 17. Many postings to http://thedailywtf.com/</li></ul>3<br />
  18. 18. © Availity, LLC | All rights reserved. <br />4<br />BugPatterns: http://thedailywtf.com/<br />4<br />
  19. 19. © Availity, LLC | All rights reserved. <br />5<br />Some<br />bug<br />Patterns:<br />
  20. 20. © Availity, LLC | All rights reserved. <br />6<br />Some<br />bug<br />Patterns:<br />
  21. 21. 7<br />Misconceptions about Bugs<br /><ul><li>Programmers are smart
  22. 22. Smart people don’t make dumb mistakes
  23. 23. WRONG!
  24. 24. Smart people make dumb mistakes
  25. 25. Common errors:
  26. 26. wrong boolean operator, forgetting parentheses, etc.
  27. 27. Misunderstood class or method !</li></li></ul><li>8<br />Can you find the Bug? <br />if (listeners == null)<br />listeners.remove(listener);<br />JDK1.6.0, b105, sun.awt.x11.XMSelection<br />
  28. 28. 9<br />Who uses FindBugs? <br /><ul><li>Developed from Research at University of Maryland
  29. 29. Google, Ebay, Sun, Wells Fargo…
  30. 30. Bill Pugh spent a year sabbatical at Google working Findbugs into their development process
  31. 31. Google runs FindBugs over all Java code
  32. 32. 1800s issues identified, > 600 fixed.
  33. 33. Ebay found 2 developers reviewing Findbugs was 10 times more effective than 2 testers</li></li></ul><li>10<br />Some Bug Categories<br />• Correctness - the code is doing something wrong, you should look at it<br />• Bad practice - the code violates good practice<br /><ul><li>Dodgy Code
  34. 34. Concurrency
  35. 35. Performance</li></ul>• Security defect<br />
  36. 36. 11<br />Can you find the Bug? <br />public String sendMessage (User user, String body, Date time) {<br /> return sendMessage(user, body, null);<br /> }<br />public String sendMessage (User user, String body, Date time, List attachments) {<br /> String xml = buildXML (body, attachments);<br /> String response = sendMessage(user, xml);<br /> return response;<br /> }<br />
  37. 37. 12<br />Infinite recursive loopHigh priority correctness<br />public String sendMessage (User user, String body, Date time) {<br /> return sendMessage(user, body, null);<br /> }<br />public String sendMessage (User user, String body, Date time, List attachments) {<br /> String xml = buildXML (body, attachments);<br /> String response = sendMessage(user, xml);<br /> return response;<br /> }<br />
  38. 38. 13<br />Can you find the Bug? <br />public String foundType() {<br /> return this.foundType();<br />}<br />
  39. 39. 14<br />Infinite recursive loop<br />public String foundType() {<br /> return this.foundType();<br />}<br />// should be <br />public String foundType() {<br /> return this.foundType;<br />}<br />• Findbugs found 5 infinite recursive loops in JDK1.6.0-b13<br />• Including this one written by Joshua Bloch<br />• Smart people make dumb mistakes<br />• 27 across all versions of JDK, 31 in Google’s Java code<br />• Embrace and fix your dumb mistakes<br />
  40. 40. 15<br />Can you find the Bug? <br />if (name != null || name.length > 0)<br />
  41. 41. 16<br />Can you find the Bug? <br />if (name != null || name.length > 0)<br />if (name != null &&name.length > 0)<br />Found in //com.sun.corba.se.impl.naming.cosnaming.NamingContextImpl<br />
  42. 42. 17<br />Can you find the Bug? <br />if (part == null | part.equals(""))<br />
  43. 43. 18<br />Can you find the Bug? <br />if (part == null | part.equals(""))<br />if (part == null ||part.equals(""))<br />Found in <br />//com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser<br />
  44. 44. 19<br />Null Pointer Bugs found in com.sun….<br />if (name != null || name.length > 0)<br />if (part == null | part.equals(""))<br />// sun.awt.x11.ScrollPanePeer<br />if (g != null)<br />paintScrollBars(g,colors);<br />g.dispose();<br />
  45. 45. © Availity, LLC | All rights reserved. <br />20<br />Can you find the Bug? <br />//BoundedThreadPool<br />private final String _lock = "LOCK";...synchronized(_lock){...}<br />
  46. 46. © Availity, LLC | All rights reserved. <br />21<br />found in Jetty….<br />//BoundedThreadPoolprivate final String _lock = "LOCK";...synchronized(_lock){...}<br />Constant Strings are shared across all other classes loaded by the JVM. Could lead to unexpected deadlocks in conjunction with other code<br />
  47. 47. 22<br />Problem?<br />public final WritableRaster filter( Raster src, WritableRasterdst) {<br />intdstLength = dst.getNumBands();<br /> // Create a new destination Raster,if needed<br /> if (dst == null)<br />dst = createCompatibleDestRaster(src);<br />
  48. 48. 23<br />Redundant Check for Null<br />Is it a bug or a redundant check?<br />public final WritableRaster filter( Raster src, WritableRasterdst) {<br />intdstLength = dst.getNumBands();<br /> // Create a new destination Raster,if needed<br /> if (dst == null)<br />dst = createCompatibleDestRaster(src);<br />can't be null because there would have been a NPE if<br />it were null<br />
  49. 49. 24<br />Can you find the Bug? <br />if (adapters == null && adapters.length == 0)<br /> return;<br />Eclipse, 3.5RC3<br />• in Eclipse since 3.2<br />•in this case adapters is probably never null<br />• Impact:<br /><ul><li> null pointer exception usually gets noticed
  50. 50. Won’t return if length is 0, error harder to find</li></li></ul><li>25<br />Problem?<br />// com.sun.xml.internal.txw2.output.XMLWriter<br />try { ... }<br />catch (IOException e) {<br /> new SAXException("Server side Exception:" + e);<br />}<br />
  51. 51. 26<br />Bad Method Call<br />// com.sun.xml.internal.txw2.output.XMLWriter<br />try { ... }<br />catch (IOException e) {<br /> new SAXException("Server side Exception:" + e);<br />}<br />Exception created and dropped rather than thrown <br />try { ... }<br />catch (IOException e) {<br />throw new SAXException("Server side Exception:" + e);<br />}<br />
  52. 52. 27<br />Problem?<br />public static String getNameById(String userId) {<br /> String str = userId;<br /> ...<br />str.replace(' ', '_');<br /> return str;<br /> } <br />
  53. 53. 28<br />Method Ignores return valueCorrectness<br />public static String getNameById(String userId) {<br /> String str = userId;<br /> ...<br />str= str.replace(' ', '_');<br /> return str;<br /> } <br />Methods whose return value shouldn't be ignored<br />• Strings are immutable, so functions like trim() and replace() return new String<br />
  54. 54. 29<br />What does it Print?<br />Integer one = 1;<br />Long addressTypeCode = 1L;<br />if (addressTypeCode.equals(one)) {<br />System.out.println("equals");<br />} else {<br />System.out.println("not equals");<br />}<br />
  55. 55. 30<br />Comparing Different Types<br />Integer one = 1;<br />Long addressTypeCode = 1L;<br />if (addressTypeCode.equals(one)) {<br />System.out.println("equals");<br />} else {<br />System.out.println("not equals");<br />}<br />According to the contract of equals(), objects of different classes should always compare as unequal;<br />
  56. 56. Incomparable equality<br /><ul><li>Using .equals to compare incompatible types
  57. 57. Using .equals to compare arrays
  58. 58. only checks if the same array
  59. 59. Checking to see if a Set<Long> contains an Integer
  60. 60. never found, even if the same integral value is contained in the map
  61. 61. Calling get(String) on a Map<Integer,String>
  62. 62. Returns false , not an error</li></ul>Silent Bugs hard to find on your own<br /><ul><li>Types not always explicit
  63. 63. May be introduced by refactoring
  64. 64. Google refactoring that changed a method to return byte[ ] rather than String</li></ul>© Availity, LLC | All rights reserved. <br />31<br />
  65. 65. 32<br />Best Way to use Findbugs<br />•Want to find an effective/profitable way to use static analysis to improve software quality<br />Mistakes<br />That<br />Don’t<br />Mistakes<br />That<br />Matter<br /> Testing<br /> Deployment<br /> Static Analysis<br />
  66. 66. 33<br />Best Way to use Findbugs<br /><ul><li>Find mistakes detected by static analysis before they are detected using more expensive techniques
  67. 67. While code is fresh in developers heads
  68. 68. Don’t be too eager to fix old issues</li></ul>Mistakes<br />That<br />Matter<br />Mistakes<br />That<br />Don’t<br /> Static Analysis<br /> Testing<br /> Deployment<br />
  69. 69. Runtime exceptions can be your friend…<br />Errors which cause a runtime exception are more easily found<br />Throwing a runtime exception is often a reasonable way to fail safely and report a failure. <br />runtime exceptions represent conditions that reflect errors in your program's logic and cannot be reasonably recovered from<br />IllegalArgumentException, NullPointerException, or IllegalStateException<br />© Availity, LLC | All rights reserved. <br />34<br />
  70. 70. Expensive Mistakes…<br /><ul><li>Mistakes that fail silently
  71. 71. silently cause the wrong answer to be computed
  72. 72. Mistakes that cause loss of money when they occur
  73. 73. Mistakes that are hard to fix</li></ul>© Availity, LLC | All rights reserved. <br />35<br />
  74. 74. 36<br />Can you find the (Google) bug ?<br />// calculate DR amount by aggregating CR amounts<br />BigDecimaldrAmount = new BigDecimal(0);<br />for (JournalEntry je: journalEntries) <br />drAmount.add(je.getCrAmount());<br />// persist to db<br />getTrxnService().saveJournalEntry(id,<br />drAmount, // aggregated amount<br /> true, // Debit<br /> "USD",<br /> "Revenue");<br />
  75. 75. 37<br />A Google Bug<br />//Ignored return value of BigDecimal.add<br />for (JournalEntry je: journalEntries) <br />drAmount.add(je.getCrAmount());<br />// should be <br />drAmount= drAmount.add(je.getCrAmount());<br />Fixed within 30 minutes of being reported<br />
  76. 76. 38<br />Bug ? <br />int value2;<br />Public boolean equals(Integer value1){<br /> return value1== intValue() ;<br />}<br />public Integer intValue() {<br /> return value2;<br />}<br />
  77. 77. 39<br />Using reference equality rather than .equals<br />int value2;<br />Public boolean equals(Integer value1){<br /> return value1.equals(intValue() );<br />}<br />public Integer intValue() {<br /> return value2;<br />}<br />For boxed primitives, == and != are computed using<br />pointer equality, but <, <=, >, >= are computed by<br />comparing unboxed primitive values<br />This can bite you on other classes (e.g., String)<br />• but boxed primitives is where people get bit<br />
  78. 78. 40<br />Bug ? <br />ConcurrentMap<Long,XmitTimeStat> xmit_time_stats = ...;<br />.....<br />stat = new XmitTimeStat();<br />xmit_time_stats.putIfAbsent(key, stat);<br />stat.xmit_rsps_sent.addAndGet(sent);<br />
  79. 79. 41<br />misusing putIfAbsentorg.jgroups.protocols.pbcast.NAKACK<br />ConcurrentMap<Long,XmitTimeStat> xmit_time_stats = ...;<br />.....<br />stat = new XmitTimeStat();<br />XmitTimeStat stat2 = xmit_time_stats.putIfAbsent(key, stat);<br />if (stat2 != null)<br /> stat = stat2;<br />stat.xmit_rsps_sent.addAndGet(sent);<br />ConcurrentMap provides putIfAbsent<br />• atomically add key -> value mapping<br />• but only if the key isnʼt already in the map<br />• if non-null value is returned, put failed and value<br />returned is the value already associated with the key<br />
  80. 80. Concurrency Bugs<br /><ul><li>Lots of concurrency bugs are found
  81. 81. They don’t cause as many problems as they should
  82. 82. Problems will probably increase with bigger core systems
  83. 83. Early reports from 768 core systems are that they have more severe problems</li></ul>© Availity, LLC | All rights reserved. <br />42<br />
  84. 84. Concurrency Bugs<br /><ul><li>Inconsistent synchronization –
  85. 85. a lock is held sometimes when field accessed
  86. 86. Problems with wait/notify –
  87. 87. e.g., call to wait() not in loop
  88. 88. unsafe lazy initialization of static field</li></ul>© Availity, LLC | All rights reserved. <br />43<br />
  89. 89. 44<br />Bug ? <br />synchronized (object) {<br />  if (<condition does not hold>) {<br />    object.wait();<br />  }<br />  // Proceed when condition holds<br />}<br />
  90. 90. 45<br />call to wait() not in loop<br />synchronized (object) {<br />  while (<condition does not hold>) {<br />    object.wait();<br />  }<br />  // Proceed when condition holds<br />}<br />
  91. 91. Concurrency Bugs<br /><ul><li>Java 5 simplified concurrency
  92. 92. In Joshua Blochʼs said: don’t lock on ConcurrentMaps</li></ul>• Bill Pugh wrote a detector for FindBugs<br />© Availity, LLC | All rights reserved. <br />46<br />
  93. 93. JBoss 5.1.0-GA<br /><ul><li>22 synchonizations on ConcurrentHashMap
  94. 94. 9 synchronizations on CopyOnWriteArrayList
  95. 95. 3 synchronizations on AtomicBoolean</li></ul>© Availity, LLC | All rights reserved. <br />47<br />
  96. 96. Security Bugs<br /><ul><li>Not exposed by normal test use cases
  97. 97. Need:
  98. 98. Risk analysis, careful design, static analysis, dynamic testing and analysis
  99. 99. Findbugsdoes simple analysis for network security vulnerabilities</li></ul>© Availity, LLC | All rights reserved. <br />48<br />
  100. 100. Some security Bugs<br /><ul><li>Vulnerability to untrusted, malicious code:
  101. 101. public static non-final fields
  102. 102. Methods that don’t defensively copy mutable arguments before storing them into fields
  103. 103. Methods that don’t defensively copy mutable values stored in fields before returning them
  104. 104. Untrusted input:
  105. 105. Included in SQL
  106. 106. included in HTTP response
  107. 107. Forming a file path </li></ul>© Availity, LLC | All rights reserved. <br />49<br />
  108. 108. Running FindBugs<br /><ul><li>Eclipse plugin
  109. 109. http://findbugs.sourceforge.net/manual/eclipse.html
  110. 110. Run with Hudson build </li></ul>© Availity, LLC | All rights reserved. <br />50<br />
  111. 111. 51<br />Findbugsplugin in Eclipse<br />
  112. 112. References<br /><ul><li>Findbugs home page
  113. 113. http://findbugs.sourceforge.net/
  114. 114. Bill Pugh FindbugsDevoxx talk
  115. 115. http://www.parleys.com/#id=2106&st=5
  116. 116. Bill Pugh Oredev talk:
  117. 117. http://oredev.org/2010/sessions/defective-java-mistakes-that-matter</li></ul>© Availity, LLC | All rights reserved. <br />52<br />
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×