Page 1
Breadcrumbs: Efficient Context Sensitivity for Dynamic Bug Detection Analyses
Michael D. Bond
University of Texas at Austin
Graham Z. BakerTufts / MIT Lincoln Laboratory
We don't make a lot of the bug detectors you use. We make a lot of the bug detectors you use better.
Samuel Z. GuyerTufts University
Page 2
Example: Dynamic data race detector
Thread A Thread B
write x
unlock mlock m
write x
read x
Page 3
Example: dynamic data race detector
Thread A Thread B
write x
unlock mlock m
write x
read xrace!
Page 4
Example: dynamic data race detector
Thread A Thread B
write x
unlock mlock m
write x
read xrace!
T@AT@A
T’@BT’@B
T’’@AT’’@A
Page 5
Example: dynamic data race detector
Thread A Thread B
write x
unlock mlock m
write x
read xrace!
How is this race reported?
T@AT@A
T’@BT’@B
T’’@AT’’@A
Page 6
Reporting a race
Thread A Thread B
write x
unlock mlock m
write x
read x
T@AT@A
T’@BT’@B
T’’@AT’’@A
loc1loc1
loc2loc2
loc3loc3
race!
Page 7
Reporting a race
Thread A Thread B
write x
read xrace!
T’@BT’@B
T’’@AT’’@A
write x
unlock mlock m
T@AT@A loc1loc1
loc2loc2
loc3loc3
AbstractDataTreeNode.indexOfChild():426
AbstractDataTreeNode.storeStrings():536
Page 8
Reporting a race
Thread A Thread B
write x
read xrace!
T’@BT’@B
T’’@AT’’@A
write x
unlock mlock m
T@AT@A loc1loc1
loc2loc2
loc3loc3
AbstractDataTreeNode.indexOfChild():426
AbstractDataTreeNode.storeStrings():536
Problem : not much information
Page 9
Full stack traces
Thread A Thread B
write x
read xrace!
T’@BT’@B
T’’@AT’’@A
write x
unlock mlock m
T@AT@A loc1loc1
loc2loc2
loc3loc3
AbstractDataTreeNode.indexOfChild():426AbstractDataTreeNode.childAtOrNull():212DeltaDataTree.lookup():666 ElementTree.includes():528 Workspace.getResourceInfo():1135Resource.getResourceInfo():973Project.hasNature():479 JavaProject.hasJavaNature():224JavaProject.computeExpandedClasspath():430JavaProject.getExpandedClasspath():1444... EclipseStarter.run():376...
AbstractDataTreeNode.storeStrings():536DataTreeNode.storeStrings():343AbstractDataTreeNode.storeStrings():541DataTreeNode.storeStrings():343...ElementTree.shareStrings():706SaveManager.shareStrings():1154...StringPoolJob.shareStrings():124...Worker.run():76...
Page 10
Context sensitivity
Big impact on static analysis Better information Better precision
Critical in modern software: Intensive code reuse (e.g., frameworks) Many small methods Highly dynamic behavior
What about dynamic analysis?
Page 11
How hard is this?
Thread A Thread B
write x
read xrace!
T’@BT’@B
T’’@AT’’@A
write x
unlock mlock m
T@AT@A loc1loc1
loc2loc2
loc3loc3
AbstractDataTreeNode.indexOfChild():426AbstractDataTreeNode.childAtOrNull():212DeltaDataTree.lookup():666 ElementTree.includes():528 Workspace.getResourceInfo():1135Resource.getResourceInfo():973Project.hasNature():479 JavaProject.hasJavaNature():224JavaProject.computeExpandedClasspath():430JavaProject.getExpandedClasspath():1444... EclipseStarter.run():376...
AbstractDataTreeNode.storeStrings():536DataTreeNode.storeStrings():343AbstractDataTreeNode.storeStrings():541DataTreeNode.storeStrings():343...ElementTree.shareStrings():706SaveManager.shareStrings():1154...StringPoolJob.shareStrings():124...Worker.run():76...
Page 12
How hard is this?
Thread A Thread B
write x
read xrace!
T’@BT’@B
T’’@AT’’@A
write x
unlock mlock m
T@AT@A loc1loc1
loc2loc2
loc3loc3
AbstractDataTreeNode.indexOfChild():426AbstractDataTreeNode.childAtOrNull():212DeltaDataTree.lookup():666 ElementTree.includes():528 Workspace.getResourceInfo():1135Resource.getResourceInfo():973Project.hasNature():479 JavaProject.hasJavaNature():224JavaProject.computeExpandedClasspath():430JavaProject.getExpandedClasspath():1444... EclipseStarter.run():376...
AbstractDataTreeNode.storeStrings():536DataTreeNode.storeStrings():343AbstractDataTreeNode.storeStrings():541DataTreeNode.storeStrings():343...ElementTree.shareStrings():706SaveManager.shareStrings():1154...StringPoolJob.shareStrings():124...Worker.run():76...EAS
YEAS
Y
Race discovered here
Race discovered here
Page 13
How hard is this?
Thread A Thread B
write x
read xrace!
T’@BT’@B
T’’@AT’’@A
write x
unlock mlock m
T@AT@A loc1loc1
loc2loc2
loc3loc3
AbstractDataTreeNode.indexOfChild():426AbstractDataTreeNode.childAtOrNull():212DeltaDataTree.lookup():666 ElementTree.includes():528 Workspace.getResourceInfo():1135Resource.getResourceInfo():973Project.hasNature():479 JavaProject.hasJavaNature():224JavaProject.computeExpandedClasspath():430JavaProject.getExpandedClasspath():1444... EclipseStarter.run():376...
AbstractDataTreeNode.storeStrings():536DataTreeNode.storeStrings():343AbstractDataTreeNode.storeStrings():541DataTreeNode.storeStrings():343...ElementTree.shareStrings():706SaveManager.shareStrings():1154...StringPoolJob.shareStrings():124...Worker.run():76...EAS
YEAS
Y
HARD
HARD
Previously recorded
information
Previously recorded
information
Page 14
Challenge
Many events might need context information e.g., race detector: every read and write (!)
Existing approaches Walk the stack: up to 100X slowdown Build calling context tree: 2-3X, plus space
Context
Context
Context
Context
Context
Context
Context
Context
Context
Context
Context
BUG
BUG
Page 15
Goal
Compact representation of calling contexts
Fast correct execution
Print out stack trace when bug detected
Efficient context sensitivity for dynamic bug detectors
Page 16
Starting point
Represent a calling context in 1 word ⎯PCC value
Computed online, low overhead ⎯<5%
BUT, no way to decode a PCC value
Probabilistic Calling ContextBond and McKinley OOPSLA 07
✓
✓
✘
Page 17
With PCC: analysis is context sensitive
Thread A Thread B
write x
unlock mlock m
write x
read xrace!
T@AT@A
T’@BT’@B
T’’@AT’’@A
pcc1pcc1
pcc2pcc2
pcc3pcc3
0xFE9A651B
0x59C2DF08
Page 18
How PCC works
Caller
Callee
m()
k()
k(); k();
j();j(); h();h();
current PCCcurrent PCC
callsite IDcallsite ID
p’ = f (p, c) p’ = f (p, c)
new PCCnew PCC
= (3p + c) mod 232
…
… …
At each call site…
Page 19
At each call site…Caller
Callee
m()
k()
k(); k();
j();j(); h();h();
current PCCcurrent PCC
callsiteIDcallsiteID
p’ = f (p, c) p’ = f (p, c)
new PCCnew PCC
= (3p + c) mod 232
…
… …
How PCC works
Page 20
Breadcrumbs
Problem: decode PCC value
Find a sequence of callsite IDs such that
p = f(…f( f( f(0, c0), c1), c2)…, cn)
i.e., invert the hash function
Page 21
Breadcrumbs
Problem: decode PCC value p
Find a sequence of callsite IDs such that
p = f(…f( f( f(0, c0), c1), c2)…, cn)
i.e., invert the hash function
Key: f is invertible Given p’ and c
unique p such that p’ = f(p, c) “Peel off” callsites until we reach 0 (main)
3 and 232 relatively
prime
3 and 232 relatively
prime
Page 22
Decode stack trace bottom-up
PCC value = 0x5A93CF09
Page 23
Decode stack trace bottom-up
PCC value = 0x5A93CF09
PCC value = 0x089C3A02
f-1(0x5A93CF09, g():2)f-1(0x5A93CF09, g():2)
Page 24
Decode stack trace bottom-up
PCC value = 0x5A93CF09
PCC value = 0x0
PCC value = 0x089C3A02
PCC value = 0x59C2DF08
f-1(0x5A93CF09, g():2)f-1(0x5A93CF09, g():2)
f-1(0x5A93CF09, d():9)
f-1(0x5A93CF09, d():9)
Page 25
Decode stack trace bottom-up
PCC value = 0x5A93CF09
…
PCC value = 0x0
PCC value = 0x089C3A02
PCC value = 0x59C2DF08
f-1(0x5A93CF09, g():2)f-1(0x5A93CF09, g():2)
f-1(0x5A93CF09, d():9)
f-1(0x5A93CF09, d():9)
…
Page 26
Problem: blind search of call graph
…
…
PCC value = 0x0
…
…
…
…
PCC value = 0x5A93CF09
Need moreinformation
Page 27
Idea: record per-callsite PCC values
…
…
…
…
…
…
0x089C3A02
Page 28
Very easy search
…
…
…
…
…
…
PCC value = 0x5A93CF09
PCC value = 0x0
Page 29
Very easy search
…
…
…
…
…
…
PCC value = 0x5A93CF09
PCC value = 0x0
f-1(0x5A93CF09, g():2)f-1(0x5A93CF09, g():2)
0x089C3A02
Page 30
Very easy search
…
…
…
…
…
…
PCC value = 0x5A93CF09
PCC value = 0x0
✓✘
f-1(0x5A93CF09, g():2)f-1(0x5A93CF09, g():2)
0x089C3A02
Page 31
Very easy search
…
…
…
…
…
…
PCC value = 0x5A93CF09
PCC value = 0x0
0x59C2DF08
f-1(0x5A93CF09, d():9)
f-1(0x5A93CF09, d():9)
f-1(0x5A93CF09, g():2)f-1(0x5A93CF09, g():2)
0x089C3A02
Page 32
Very easy search
…
…
…
…
…
…
PCC value = 0x5A93CF09
PCC value = 0x0
✓ ✘0x59C2DF08
f-1(0x5A93CF09, d():9)
f-1(0x5A93CF09, d():9)
f-1(0x5A93CF09, g():2)f-1(0x5A93CF09, g():2)
0x089C3A02
Page 33
Very easy search
…
…
…
…
…
…
PCC value = 0x5A93CF09
PCC value = 0x0
0x59C2DF08
f-1(0x5A93CF09, d():9)
f-1(0x5A93CF09, d():9)
f-1(0x5A93CF09, g():2)f-1(0x5A93CF09, g():2)
0x089C3A02
…
Page 34
antlrcharteclip
se fophsql
dbjythonluind
expmdxala
n jbb
geomean
0 20
40
60
80
100
120
140
160
% overhead
With per-callsite setsJikesRVMDaCapo benchmarks
# set ops
528m201m857m21m158
m3,624m217
m270m738m137m
PCC only
Page 35
Observation
…
…
…
…
…
…
Page 36
Idea: stop tracking hot call sites
…
…
…
…
…
Page 37
antlrcharteclip
se fophsql
dbjythonluind
expmdxala
n jbb
geomean
0 20
40
60
80
100
120
140
160
% overhead
t = 100,000
t = 100
t = 10,000
No threshold
t = 1,000
PCC only
Is it enough information?
Tunable “hotnes
s” threshol
d
Page 38
Decoding: hybrid search
…
…
…
…
…
…
PCC value = 0x5A93CF09
Page 39
Decoding: hybrid search
…
…
…
…
…
…
PCC value = 0x5A93CF09
✓
f-1(0x5A93CF09, g():2)f-1(0x5A93CF09, g():2)
0x089C3A02
Page 40
Decoding: hybrid search
…
…
…
…
…
…
PCC value = 0x5A93CF09
0x59C2DF08
f-1(0x5A93CF09, d():9)
f-1(0x5A93CF09, d():9)
f-1(0x5A93CF09, g():2)f-1(0x5A93CF09, g():2)
0x089C3A02
Page 41
Heuristic search (see paper)
…
…
…
…
…
…
PCC value = 0x5A93CF09
0x59C2DF08
f-1(0x5A93CF09, d():9)
f-1(0x5A93CF09, d():9)
f-1(0x5A93CF09, g():2)f-1(0x5A93CF09, g():2)
0x089C3A02
Page 42
antlrcharteclip
se fophsql
dbjythonluind
expmdxala
n jbb
0 20
40
60
80
100
120
140
160
% overhead
100%
100%
100%
100%
100%
47% 47% 47% 82% 95%
100%
100%
100%
100%
100%
89% 95% 95% 97% 97%
Race detectionresults
(go to Pacer talk tomorrow!)
t = 100,000
t = 100
t = 10,000
No threshold
t = 1,000
geomean
Page 43
Summary
Make any dynamic bug detector context sensitive
More in the paper: Description of search algorithm What kinds of bug detectors will benefit Results for two real bug detectors
(both quantitative and qualitative)
Available as patch to JikesRVM
Page 44
Related work
Reconstruct contexts from PC and SP [Mytkowicz et al. 2009] [Inoue and Nakatani 2009]
Very low overhead, but little entropy in these values
Path profiling approach [Sumner et al. 2010]
Uses multiple integers to represent calling context exactly
Both require offline training, pre-computed infoChallenge for complex, highly dynamic software
Page 45
Thank You
Questions?
Page 46
Goals
Represent calling context compactlyEasily take place of static program locations
Fast correct executionFor deployed or field-testing environment
Decode back into stack trace when neededCould expensive, but cost paid offline
Page 47
Calling context representation
Calling context stored in 1 word ⎯ PCC valueEssentially a hash of sequence of call site IDs
Computed online, low overhead <5%PCC values computed incrementally, at each call site
BUT, no way to decode a PCC valueCan distinguish, but not identify calling contexts
✓
✓
✘
Started with Probabilistic Calling Context Bond and McKinley OOPSLA 07
Page 48
Summary
Make any dynamic bug detector context sensitive
Tunable overhead/precision tradeoffSweet spot:
10% to 20% overhead at threshold 1,000 to 10,000
Challenges Long sequences of hot callsites Deep recursion
Available as patch to JikesRVM
Page 49
antlr
chart
eclipse
fop
hsqldb
jython
luindex
pmd
xalan
jbb
geomean
0 20 40 60 80 100 120 140 160
% overhead
Tradeoff: cost vs
decoding
t = 100,000
t = 100
t = 10,000
No threshold
t = 1,000
PCC only
Page 50
100%
100%
100%
100%
100%
antlrcharteclip
se fophsql
dbjythonluind
expmdxala
n jbb
geomean
0 20
40
60
80
100
120
140
160
% overhead
47% 47% 47% 82% 95%
100%
100%
100%
100%
100%
89% 95% 95% 97% 97%