Emina Torlak and Satish Chandra
IBM T.J. Watson Research Center Hawthorne, NY
Effective interprocedural resource leak detection Emina Torlak and - - PowerPoint PPT Presentation
Effective interprocedural resource leak detection Emina Torlak and Satish Chandra IBM T.J. Watson Research Center Hawthorne, NY Resource leaks in Java void test(File file, String enc) throws IOException { PrintWriter out = null; Unlike
IBM T.J. Watson Research Center Hawthorne, NY
void test(File file, String enc) throws IOException { PrintWriter out = null; try { try {
new OutputStreamWriter( new FileOutputStream(file), enc)); } catch (UnsupportedEncodingException ue) {
}
} catch (IOException e) { } finally { if (out != null)
} }
2
Simplified code excerpt from ANT
void test(File file, String enc) throws IOException { PrintWriter out = null; try { try {
new OutputStreamWriter( new FileOutputStream(file), enc)); } catch (UnsupportedEncodingException ue) {
}
} catch (IOException e) { } finally { if (out != null)
} }
2
Simplified code excerpt from ANT close() releases the resource
void test(File file, String enc) throws IOException { PrintWriter out = null; try { try {
new OutputStreamWriter( new FileOutputStream(file), enc)); } catch (UnsupportedEncodingException ue) {
}
} catch (IOException e) { } finally { if (out != null)
} }
3
Simplified code excerpt from ANT
void test(File file, String enc) throws IOException { PrintWriter out = null; try { try {
new OutputStreamWriter( new FileOutputStream(file), enc)); } catch (UnsupportedEncodingException ue) {
}
} catch (IOException e) { } finally { if (out != null)
} }
3
handle to the FileOutputStream is lost, so it’s never closed Simplified code excerpt from ANT
4
Excerpt from an online bug database
4
Excerpt from an online bug database
5
access paths
analysis
exceptions
resources
6 void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (isr != null) isr.close(); } }
Tracking FileInputStream
7
void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (isr != null) isr.close(); } }
Tracking FileInputStream
7
[•, { fis }]
void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (isr != null) isr.close(); } }
Tracking FileInputStream
7
[•, { fis }] [•, { fis, isr.sd.in }]
void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (isr != null) isr.close(); } }
Tracking FileInputStream
7
[•, { fis }] [•, { fis, isr.sd.in }] [•, { fis, isr.sd.in }]
void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (isr != null) isr.close(); } }
Tracking FileInputStream
7
[•, { fis }] [•, { fis, isr.sd.in }] [•, { fis, isr.sd.in }]
void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (isr != null) isr.close(); } }
Tracking FileInputStream
stop tracking it
8
void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (isr != null) isr.close(); } }
Tracking FileInputStream
8
[•, { fis }]
void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (isr != null) isr.close(); } }
Tracking FileInputStream
8
[•, { fis }] [•, { fis }]
void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (isr != null) isr.close(); } }
Tracking FileInputStream
8
[•, { fis }] [•, { fis }] [•, { fis }]
void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (isr != null) isr.close(); } }
Tracking FileInputStream
8
[•, { fis }] [•, { fis }] [•, { fis }] [•, { fis }]
void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (isr != null) isr.close(); } }
Tracking FileInputStream
8
[•, { fis }] [•, { fis }] [•, { fis }] [•, { }] resource leaking: no handles left [•, { fis }]
void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (isr != null) isr.close(); } }
Tracking FileInputStream
8
[•, { fis }] [•, { fis }] [•, { fis }] [•, { }] resource leaking: no handles left [•, { fis }]
void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (isr != null) isr.close(); } }
Tracking FileInputStream
9
void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (fis != null) fis.close(); } }
Tracking at most 3 paths of length 1 to FileInputStream (d = 1, b = 3)
9
[•, { fis }]
void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (fis != null) fis.close(); } }
Tracking at most 3 paths of length 1 to FileInputStream (d = 1, b = 3)
9
[•, { fis }] [•, { }]
void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (fis != null) fis.close(); } }
Tracking at most 3 paths of length 1 to FileInputStream (d = 1, b = 3)
resource assumed to leak: cannot track {fis, isr.sd.in}
9
[•, { fis }] [•, { }]
void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (fis != null) fis.close(); } }
Tracking at most 3 paths of length 1 to FileInputStream (d = 1, b = 3)
resource assumed to leak: cannot track {fis, isr.sd.in}
10
false positive true positive
10
false positive true positive d = 1, b = 3
10
false positive true positive d = 1, b = 3 d = 3, b = 5
10
false positive true positive d = 1, b = 3 d = 3, b = 5 d = 5, b = 5
10
false positive true positive d = 1, b = 3 d = 3, b = 5 d = 5, b = 5 W A
11
Tracking FileInputStream with d = 1, b = 3
void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (isr != null) isr.close(); } }
[•, { fis }] [•, { fis }] [•, { fis }] [•, { }] [•, { fis }]
[•, { }]
void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (fis != null) fis.close(); } }
Tracking FileInputStream with d = 1, b = 3
12 void test(File f, String e) throws IOException { FileInputStream fis = null; try { fis = new FileInputStream(f); } catch (IOException e) { } Integer i = new Integer(0); if (fis != null) fis.close(); }
12 void test(File f, String e) throws IOException { FileInputStream fis = null; try { fis = new FileInputStream(f); } catch (IOException e) { } Integer i = new Integer(0); if (fis != null) fis.close(); }
may throw an OutOfMemoryError, but unlikely
…
12 void test(File f, String e) throws IOException { FileInputStream fis = null; try { fis = new FileInputStream(f); } catch (IOException e) { } Integer i = new Integer(0); if (fis != null) fis.close(); }
may throw an OutOfMemoryError, but unlikely
13 void test(File f, String e) throws IOException { FileInputStream fis = null; try { fis = new FileInputStream(f); } catch (IOException e) { } Integer i = new Integer(0); if (fis != null) fis.close(); }
may throw an OutOfMemoryError, but unlikely
14 void test(File f, String e) throws IOException { InputStreamReader isr = new InputStreamReader( new FileInputStream(f), e); } void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (fis != null) fis.close(); } }
Tracking FileInputStream and InputStreamReader
14 void test(File f, String e) throws IOException { InputStreamReader isr = new InputStreamReader( new FileInputStream(f), e); } void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (fis != null) fis.close(); } }
Tracking FileInputStream and InputStreamReader
14 void test(File f, String e) throws IOException { InputStreamReader isr = new InputStreamReader( new FileInputStream(f), e); } void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (fis != null) fis.close(); } }
wrapper not closed but the wrapped resource is Tracking FileInputStream and InputStreamReader
14 void test(File f, String e) throws IOException { InputStreamReader isr = new InputStreamReader( new FileInputStream(f), e); } void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (fis != null) fis.close(); } }
wrapper not closed but the wrapped resource is Tracking FileInputStream and InputStreamReader
14 void test(File f, String e) throws IOException { InputStreamReader isr = new InputStreamReader( new FileInputStream(f), e); } void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (fis != null) fis.close(); } }
wrapper not closed but the wrapped resource is wrapper and wrapped resource are both leaking Tracking FileInputStream and InputStreamReader
15 void test(File f, String e) throws IOException { InputStreamReader isr = new InputStreamReader( new FileInputStream(f), e); }
void test(File f, String e) throws IOException { InputStreamReader isr = null; FileInputStream fis = null; try { fis = new FileInputStream(f); isr = new InputStreamReader(fis, e); } finally { if (fis != null) fis.close(); } }
wrapper not closed but the wrapped resource is wrapper and wrapped resource are both leaking
16 150,000 300,000 450,000 600,000 A
N T
1 . 7 B
A T I K
1 . 6 B
I R T
2 . 5 F
R O S T W I R E
4 . 1 7 T
O M C A T
6 .
102,220 127,363 572,744 97,048 63,033 9,981 16,279 69,293 11,187 6,952
Application size # classes # methods
4.17, TOMCAT 6.0
16 150,000 300,000 450,000 600,000 A
N T
1 . 7 B
A T I K
1 . 6 B
I R T
2 . 5 F
R O S T W I R E
4 . 1 7 T
O M C A T
6 .
102,220 127,363 572,744 97,048 63,033 9,981 16,279 69,293 11,187 6,952
Application size # classes # methods
4.17, TOMCAT 6.0
17 30 60 90 120 150 〈 1 , 3 〉 〈 3 , 3 〉 〈 3 , 5 〉 〈 5 , 5 〉 〈 1 , 1 〉 Ant 1.7 # of reports 〈path length, # of paths〉 high rank true positives low rank true positives high rank false positives low rank false positives
18
15 30 45 60 〈 1 , 3 〉 〈 3 , 3 〉 〈 3 , 5 〉 〈 5 , 5 〉 〈 1 , 1 〉 Analysis time vs fact size analysis time (sec) 〈path length, # of paths〉
BATIK ANT FROSTWIRE TOMCAT BIRT
quality reports
resource disposal
19