Presentation is loading. Please wait.

Presentation is loading. Please wait.

Static Deadlock Detection for Java Libraries

Similar presentations


Presentation on theme: "Static Deadlock Detection for Java Libraries"— Presentation transcript:

1 Static Deadlock Detection for Java Libraries
Amy Williams, William Thies, and Michael D. Ernst Massachusetts Institute of Technology

2 Deadlock Each deadlocked thread attempts to acquire a lock held by another thread Can halt entire program execution Difficult to expose during testing Once exposed, difficult to replicate Example: a StringBuffer a, b; Thread 1: a.append(b); locks a, b Thread 2: b.append(a); locks b, a b

3 Deadlock in Libraries Library writers may wish to provide guarantees
JDK’s StringBuffer documentation says class is thread-safe Goal: find client calls that deadlock library or verify that none exist lib writers can document how to avoid deadlock

4 Analyzing Programs / Libraries
For Programs: For Libraries: Method Calls Fixed Consider all calling patterns Aliasing Possibilities Consider aliasing induced by any program Number of Threads Might be known Unbounded

5 Deadlock from Sun’s JDK
import java.beans.beancontext.*; BeanContextSupport support = new BeanContextSupport(); Object source = new Object(); PropertyChangeEvent event = new PropertyChangeEvent(source, "beanContext", ...); support.add(source); support.vetoableChange(event); Deadlock previously unknown to us Thread 1: support.propertyChange(event); locks global, field Thread 2: support.remove(source); locks field, global Also found 13 other deadlocks

6 Analysis Overview Build lock-order graph representing locking behavior of each method in library Combine graphs for all public methods into single graph Detect cycles in this graph, which indicate deadlock possibilities Analysis properties: reports all deadlocks, context-sensitive, flow-sensitive

7 JDK Source (simplified)
interface BeanContext { public static final Object globalHierarchyLock; } class BeanContextSupport { protected HashMap children; public boolean remove(Object targetChild) { synchronized(BeanContext.globalHierarchyLock) { ... synchronized(children) { children.remove(targetChild); Object HashMap Graph gives lock order for remove method, using types instead of the identifiers specific to the method Continued...

8 JDK Source (simplified), cont.
class BeanContextSupport { protected HashMap children; public void propertyChange(PropertyChangeEvent pce) { ... Object source = pce.getSource(); synchronized(children) { if (...) { remove(source); } Object HashMap public boolean remove(Object targetChild) { synchronized (BeanContext.globalHierarchyLock) { ... }

9 Merged Graph When merged, graphs indicate possible locking orders of all methods Cycles indicate possible deadlock Expose cases in which threads lock set of locks in different (conflicting) orders Object HashMap Cycle corresponds to deadlock shown in preceding slide

10 Outline Introduction Deadlock Detection Algorithm Results
Related Work and Conclusions

11 Synchronization in Java
Locking is hierarchical, performed using synchronized statement Multiple locks acquired via nested synchronized statements Synchronizing on previously acquired lock always succeeds Considered a no-op for our analysis Synchronized methods sugar for synchronizing on this synchronized (lock1) { synchronized (lock2) { ... } Analysis relies on the fact that locking in Java is performed hierarchically

12 Synchronization in Java
wait() and notify() methods Java 1.5’s non-hierarchical primitives (in java.concurrent package) not covered by analysis Usage rare; recommended only for expert programmers

13 Analysis Overview Build lock-order graph representing locking behavior of each method in library Callee graphs integrated into caller Iterate to fixed point; termination guaranteed Combine graphs for all public methods into single graph Detect cycles in this graph, which indicate deadlock possibilities

14 Lock-order Graph Directed graph that represents the order in which locks are acquired Nodes represent may-alias sets Allows graphs from different methods to be combined Edges mean the source lock held while destination lock acquired Cycles indicate possibility of deadlock set 1 set 2 set 3 Graph indicates that an object from set 1 is locked and, while that lock is held, an object from set 2 is locked, likewise for set 3, etc.

15 Example Library public void deposit(Bank b1, Client c1) {
synchronized (b1) { synchronized (c1) { ... } public void openAccount(Bank b2, Client c2) { synchronized (b2) { synchronized (c2) { deposit(b2, c2); Contrived library containing banking functions used to illustrate the analysis

16 Example Analysis: deposit()
public void deposit(Bank b1, Client c1) { synchronized (b1) { synchronized (c1) { ... } public void openAccount(Bank b2, Client c2) { synchronized (b2) { synchronized (c2) { deposit(b2, c2); Graph: Ordered list of locks held: [] Analysis builds a graph and tracks, for each program point, the list of locks held at that point

17 Example Analysis: deposit()
public void deposit(Bank b1, Client c1) { synchronized (b1) { synchronized (c1) { ... } public void openAccount(Bank b2, Client c2) { synchronized (b2) { synchronized (c2) { deposit(b2, c2); Graph: Ordered list of locks held: []

18 Example Analysis: deposit()
public void deposit(Bank b1, Client c1) { synchronized (b1) { synchronized (c1) { ... } public void openAccount(Bank b2, Client c2) { synchronized (b2) { synchronized (c2) { deposit(b2, c2); Graph: Ordered list of locks held: [b1] No locks held, so node is root b1 A node is added to the graph for each newly acquired lock and an edge is added from the last acquired lock; when no other locks are held, the node is designated as a root of the graph. Roots are used when integrating callee graphs into callers as shown later. We track locks using object identifiers which can be thought of as the variable name for the object where the method is in SSA form.

19 Example Analysis: deposit()
public void deposit(Bank b1, Client c1) { synchronized (b1) { synchronized (c1) { ... } public void openAccount(Bank b2, Client c2) { synchronized (b2) { synchronized (c2) { deposit(b2, c2); Graph: Ordered list of locks held: [b1] b1

20 Example Analysis: deposit()
public void deposit(Bank b1, Client c1) { synchronized (b1) { synchronized (c1) { ... } public void openAccount(Bank b2, Client c2) { synchronized (b2) { synchronized (c2) { deposit(b2, c2); Graph: Ordered list of locks held: [b1, c1] b1 c1 When some other lock is held, an edge is added from the most recently acquired lock to the newly acquired one.

21 Example Analysis: deposit()
public void deposit(Bank b1, Client c1) { synchronized (b1) { synchronized (c1) { ... } public void openAccount(Bank b2, Client c2) { synchronized (b2) { synchronized (c2) { deposit(b2, c2); Graph: Ordered list of locks held: [b1, c1] b1 c1 When exiting a synchronized statement, list of locks held is updated, but graph remains the same. In this way, the final graph of the function includes the locking behavior over all paths of control.

22 Example Analysis: deposit()
public void deposit(Bank b1, Client c1) { synchronized (b1) { synchronized (c1) { ... } public void openAccount(Bank b2, Client c2) { synchronized (b2) { synchronized (c2) { deposit(b2, c2); Graph: Ordered list of locks held: [b1] b1 c1

23 Lock-order graph for deposit()
public void deposit(Bank b1, Client c1) { synchronized (b1) { synchronized (c1) { ... } public void openAccount(Bank b2, Client c2) { synchronized (b2) { synchronized (c2) { deposit(b2, c2); Graph: b1 c1

24 Example Analysis: openAccount()
deposit’s graph: public void deposit(Bank b1, Client c1) { synchronized (b1) { synchronized (c1) { ... } public void openAccount(Bank b2, Client c2) { synchronized (b2) { synchronized (c2) { deposit(b2, c2); Graph: Ordered list of locks held: [] b1 c1

25 Example Analysis: openAccount()
deposit’s graph: public void deposit(Bank b1, Client c1) { synchronized (b1) { synchronized (c1) { ... } public void openAccount(Bank b2, Client c2) { synchronized (b2) { synchronized (c2) { deposit(b2, c2); Graph: Ordered list of locks held: [b2] b1 c1 b2

26 Example Analysis: openAccount()
deposit’s graph: public void deposit(Bank b1, Client c1) { synchronized (b1) { synchronized (c1) { ... } public void openAccount(Bank b2, Client c2) { synchronized (b2) { synchronized (c2) { deposit(b2, c2); Graph: Ordered list of locks held: [c2] b1 c1 c2 b2 c2 acquired while no other lock is held, so it is a root just as b2 is

27 Example Analysis: openAccount()
deposit’s graph: public void deposit(Bank b1, Client c1) { synchronized (b1) { synchronized (c1) { ... } public void openAccount(Bank b2, Client c2) { synchronized (b2) { synchronized (c2) { deposit(b2, c2); Graph: Ordered list of locks held: [c2] b1 c1 c2 b2

28 Example Analysis: openAccount()
current graph: deposit’s graph: public void deposit(Bank b1, Client c1) { synchronized (b1) { synchronized (c1) { ... } public void openAccount(Bank b2, Client c2) { synchronized (b2) { synchronized (c2) { deposit(b2, c2); Graph: Ordered list of locks held: [c2] c2 b2 b1 c1 call to deposit(): we save the current graph for openAccount()…

29 Call to deposit(): update copy of deposit’s graph ^
current graph: deposit’s graph: public void deposit(Bank b1, Client c1) { synchronized (b1) { synchronized (c1) { ... } public void openAccount(Bank b2, Client c2) { synchronized (b2) { synchronized (c2) { deposit(b2, c2); Graph: Ordered list of locks held: [c2] c2 b2 b1 c1 b1 b2 c1 … and bring up a copy of the graph for deposit(), then update it for the calling context. This slide contains animations which should be viewed. b2

30 Call to deposit(): update copy of deposit’s graph ^
current graph: deposit’s graph: public void deposit(Bank b1, Client c1) { synchronized (b1) { synchronized (c1) { ... } public void openAccount(Bank b2, Client c2) { synchronized (b2) { synchronized (c2) { deposit(b2, c2); Graph: Ordered list of locks held: [c2] c2 b2 b1 c1 b2 c2 c1 Continue update for calling context c2

31 Call to deposit(): update copy of deposit’s graph ^
current graph: deposit’s graph: public void deposit(Bank b1, Client c1) { synchronized (b1) { synchronized (c1) { ... } public void openAccount(Bank b2, Client c2) { synchronized (b2) { synchronized (c2) { deposit(b2, c2); Graph: Ordered list of locks held: [c2] c2 b2 b1 c1 b2 c2 Because the lock for c2 is already held, the lock acquire of c1 inside deposit() is a no-op, so the corresponding node is removed.

32 Call to deposit(): update copy of deposit’s graph ^
current graph: deposit’s graph: public void deposit(Bank b1, Client c1) { synchronized (b1) { synchronized (c1) { ... } public void openAccount(Bank b2, Client c2) { synchronized (b2) { synchronized (c2) { deposit(b2, c2); Graph: Ordered list of locks held: [c2] c2 b2 b1 c1 b2 b2

33 Call to deposit(): insert deposit’s graph
public void deposit(Bank b1, Client c1) { synchronized (b1) { synchronized (c1) { ... } public void openAccount(Bank b2, Client c2) { synchronized (b2) { synchronized (c2) { deposit(b2, c2); Graph: Ordered list of locks held: [c2] b1 c1 c2 b2 b2 Bring back up current graph for openAccount(), and link it with the updated graph for the callee…

34 Call to deposit(): insert deposit’s graph
public void deposit(Bank b1, Client c1) { synchronized (b1) { synchronized (c1) { ... } public void openAccount(Bank b2, Client c2) { synchronized (b2) { synchronized (c2) { deposit(b2, c2); Graph: Ordered list of locks held: [c2] b1 c1 c2 b2 b2 Edge(s) added from most recently acquired lock to roots of callee graph.

35 Lock-order graph for openAccount()
deposit’s graph: public void deposit(Bank b1, Client c1) { synchronized (b1) { synchronized (c1) { ... } public void openAccount(Bank b2, Client c2) { synchronized (b2) { synchronized (c2) { deposit(b2, c2); Graph: b1 c1 c2 b2

36 Analysis Overview Build lock-order graph representing locking behavior of each method in library Callee graphs integrated into caller Iterate to fixed point; termination guaranteed Combine graphs for all public methods into single graph Detect cycles in this graph, which indicate deadlock possibilities

37 Combine Graphs Graph for deposit(): Graph for openAccount(): b1 c2 b2
To combine graphs, root node markers are dropped, since they are only necessary in the graph building stage of the analysis.

38 Combine Graphs Graph for deposit(): Graph for openAccount(): Bank
Client Bank Client Nodes labels are changed from local variable names to may-alias sets (types provide conservative may-alias information). May-alias sets are used in order to determine whether a lock acquire in one method might be over the same object as another method.

39 Combine Graphs Graph for deposit(): Graph for openAccount():
Final graph: Bank Client Bank Client Graphs from methods are combined, with nodes having the same may-alias set merged. (Animation should be viewed.)

40 Analysis Overview Build lock-order graph representing locking behavior of each method in library Callee graphs integrated into caller Iterate to fixed point; termination guaranteed Combine graphs for all public methods into single graph Detect cycles in this graph, which indicate deadlock possibilities

41 Cycle in Combined Graph
Cycles indicate possibility of deadlock, and deadlock is possible Final graph: Client Bank

42 Code that Deadlocks Library
public void deposit(Bank b1, Client c1) { synchronized (b1) { synchronized (c1) { ... } public void openAccount(Bank b2, Client c2) { synchronized (b2) { synchronized (c2) { deposit(b2, c2); Bank b; Client c; Thread 1: openAccount(b, c); locks c, b Thread 2: deposit(b, c); locks b, c

43 Beyond Public Methods Graph for library must also include static initializers and finalizers Method calls to Thread.start() handled specially Lock-order graphs for receiver’s run() method integrated into graph for whole library ECOOP paper omitted these cases; addressed in forthcoming Technical Report

44 Handling wait() and notify()
Calling wait() releases and later reacquires receiver’s lock Considered no-op if receiver’s lock most recently acquired Can change lock order even if receiver’s lock is held

45 Handling wait() and notify()
Calling wait() releases and later reacquires receiver’s lock Considered no-op if receiver’s lock most recently acquired Can change lock order even if receiver’s lock is held synchronized (a) { synchronized (b) { b.wait() } a b

46 Handling wait() and notify()
Calling wait() releases and later reacquires receiver’s lock Considered no-op if receiver’s lock most recently acquired Can change lock order even if receiver’s lock is held synchronized (a) { synchronized (b) { b.wait() } a b

47 Handling wait() and notify()
Calling wait() releases and later reacquires receiver’s lock Considered no-op if receiver’s lock most recently acquired Can change lock order even if receiver’s lock is held synchronized (a) { synchronized (b) { a.wait() } a b

48 Handling wait() and notify()
Calling wait() releases and later reacquires receiver’s lock Considered no-op if receiver’s lock most recently acquired Can change lock order even if receiver’s lock is held synchronized (a) { synchronized (b) { a.wait() } a b

49 Deadlock using wait() Object a, b; Thread 1: synchronized (a) {
synchronized (b) { a.wait(); } locks a, b and b, a

50 Deadlock using wait() Object a, b; Thread 1: synchronized (a) {
synchronized (b) { a.wait(); } locks a, b and b, a a b

51 Deadlock using wait() Object a, b; Thread 1: synchronized (a) {
synchronized (b) { a.wait(); } locks a, b and b, a b

52 Deadlock using wait() Object a, b; Thread 1: synchronized (a) {
synchronized (b) { a.wait(); } locks a, b and b, a Thread 2: synchronized (a) { a.notify(); synchronized (b) { } locks a, b b

53 Deadlock using wait() Object a, b; Thread 1: synchronized (a) {
synchronized (b) { a.wait(); } locks a, b and b, a Thread 2: synchronized (a) { a.notify(); synchronized (b) { } locks a, b a b

54 Deadlock using wait() Object a, b; Thread 1: synchronized (a) {
synchronized (b) { a.wait(); } locks a, b and b, a Thread 2: synchronized (a) { a.notify(); synchronized (b) { } locks a, b a b

55 Deadlock using wait() Object a, b; Thread 1: synchronized (a) {
synchronized (b) { a.wait(); } locks a, b and b, a Thread 2: synchronized (a) { a.notify(); synchronized (b) { } locks a, b a b

56 Deadlock using wait() Object a, b; Thread 1: synchronized (a) {
synchronized (b) { a.wait(); } locks a, b and b, a Thread 2: synchronized (a) { a.notify(); synchronized (b) { } locks a, b a Thread 1 b

57 Deadlock using wait() Object a, b; Thread 1: synchronized (a) {
synchronized (b) { a.wait(); } locks a, b and b, a Thread 2: synchronized (a) { a.notify(); synchronized (b) { } locks a, b a Thread 1 b Thread 2

58 Deadlock using wait() Deadlock! Object a, b; Thread 1:
synchronized (a) { synchronized (b) { a.wait(); } locks a, b and b, a Thread 2: synchronized (a) { a.notify(); synchronized (b) { } locks a, b a Deadlock! Thread 1 b Thread 2

59 Improving Precision We further refine may-alias sets and type information in certain cases (see paper) Unaliased fields Caller / callee type resolution Final and effectively-final fields These optimizations prove very effective: one library went from 909 reports to only 1 Context-sensitivity (integrating callee graphs) greatly improved precision Without context-sensitivity, methods that acquire a lock such as “this” and call another method locking this produce a false report. Thus, even if only public method in JDK were println(), a context-insensitive analysis would report a deadlock possibilty.

60 Outline Introduction Deadlock Detection Algorithm Results
Related Work and Conclusions

61 Deadlocks Detected Analysis is sound: detects all deadlocks in library under analysis Assumptions: Clients assumed to respect lock order of library for any shared locks Callbacks are not modeled The client code may call any public method Would introduce many locking orders which are unlikely in practice Reflection not handled Detects all deadlocks in which the threads are blocked in the library under analysis. Without first assumption, client could deadlock a library if it has access to a single object that the library locks. A conservative model of callbacks would require assuming that the callback method calls every public method in the library. Most callbacks are to methods like hashCode(), which are unlikely to need to call into the library again.

62 Deadlock Reports Each report: set of variables possibly involved in deadlock Also provided: set of methods possibly deadlocking using those variables Sometimes many call sequences per report This reporting style means that different reports correspond to truly distinct deadlocks, and is a conservative metric for counting deadlocks. The goal is to capture in a single report, a conceptual class of deadlocks, and includes all “paths” that can invoke it. Our experience showed that most methods in a report were from a single class and contained similar control flow.

63 Results: Overview Analyzed 18 libraries
13 libraries verified to be deadlock-free Each library analyzed in under 3 minutes 5 libraries not verified Exhibited 14 distinct deadlocks Each library analyzed in under 3 minutes employing filtering heuristics 18 open source libraries, most obtained from SourceForge and Savannah

64 Deadlock-Free Libraries
Library sync kLOC Reports jcurzez 24 4 1 httpunit 17 23 jasperreports 11 67 croftsoft 14 2 dom4j 6 41 cewolf 7 jfreechart 5 125 htmlparser 22 jpcap 8 treemap PDFBox 28 UJAC 63 JOscarLib

65 Deadlock-Free Libraries
Library sync kLOC Reports jcurzez 24 4 1 httpunit 17 23 jasperreports 11 67 croftsoft 14 2 dom4j 6 41 cewolf 7 jfreechart 5 125 htmlparser 22 jpcap 8 treemap PDFBox 28 UJAC 63 JOscarLib 10 libraries automatically proved deadlock free by the tool.

66 Deadlock-Free Libraries
Library sync kLOC Reports jcurzez 24 4 1 httpunit 17 23 jasperreports 11 67 croftsoft 14 2 dom4j 6 41 cewolf 7 jfreechart 5 125 htmlparser 22 jpcap 8 treemap PDFBox 28 UJAC 63 JOscarLib Manually verified 4 reports to be false positives 3 libraries produced 4 reports which we inspected and verified to be false positives.

67 Non-verified Libraries
Library sync kLOC Reports Deadlocks Found JDK 1458 419 Out of Memory 7 Classpath 754 295 5 ProActive 199 63 ≥ 196 2 Jess 111 27 ≥ 269 sdsu 69 26 ≥ 20,479 Analysis as presented so far is inefficient in both time and space, and produces too many reports to be of practical use for these libraries. Deadlocked JVM for all 14 cases

68 Filtering Heuristics Full analysis can yield too many reports
Cycle length Do not report cycles longer than 2 nodes Assume runtime type same as declared type Lock declared as Object cannot alias with subclasses May filter out real deadlocks

69 Non-verified Libraries
Library sync kLOC Reports Reports (Filtered) Deadlocks Found JDK 1458 419 Out of Memory 72 7 Classpath 754 295 32 5 ProActive 199 63 ≥ 196 3 2 Jess 111 27 ≥ 269 23 sdsu 69 26 ≥ 20,479 Deadlocked JVM for all 14 cases

70 Non-verified Libraries
Library sync kLOC Reports Reports (Filtered) Deadlocks Found JDK 1458 419 Out of Memory 72 7 Classpath 754 295 32 5 ProActive 199 63 ≥ 196 3 2 Jess 111 27 ≥ 269 23 sdsu 69 26 ≥ 20,479 Because of our reporting style these counts are conservative. There are multiple ways to deadlock some of these reports; in one case there are at least 50 methods that can be called to invoke the particular deadlock Deadlocked JVM for all 14 cases

71 Deadlocks Found JDK Classpath BeanContextSupport × StringBuffer
Not Implemented StringBuffer synchronized Collections PrintWriter/CharArrayWriter java.awt.dnd.DropTarget Not synchronized java.awt.EventQueue java.awt.Menu java.util.SimpleTimeZone java.util.logging.Logger Classpath’s java.awt.Menu does not include the shortcuts() method that contains a deadlock in the JDK. Classpath’s java.awt.dnd.DropTarget class performs no synchronization; data races possible. JDK’s SimpleTimeZone.equals() method is not synchronized; race possible. JDK’s java.util.logging.Logger implementation doesn’t perform synchronized operations on the parent field, though other locks protect its modification so it appears that no race is possible. ProActive: ProxyForGroup, AbstractDataObject

72 PrintWriter/CharArrayWriter: JDK
class Writer { Object lock; protected Writer() { lock = this; } protected Writer(Object lock) { this.lock = lock; class PrintWriter extends Writer { Writer out; public PrintWriter(Writer out) { super(out); this.out = out; } public void write(…) { synchronized (lock) { out.write(…) } } } CharArrayWriter c = new CharArrayWriter(); PrintWriter p1 = new PrintWriter(c); PrintWriter p2 = new PrintWriter(p1); c.lock = c p1.lock = c p2.lock = p1 Thread 1: p2.write(…); locks p1, c Thread 2: c.writeTo(p2); locks c, p1

73 PrintWriter/CharArrayWriter: Classpath
class Writer { Object lock; protected Writer() { lock = this; } protected Writer(Object lock) { this.lock = lock; class PrintWriter extends Writer { public PrintWriter(Writer out) { super(out.lock); } public void write(…) { synchronized (lock) { …} CharArrayWriter c = new CharArrayWriter(); PrintWriter p1 = new PrintWriter(c); PrintWriter p2 = new PrintWriter(p1); c.lock = c p1.lock = c p2.lock = c No deadlock!

74 ProActive’s ProxyForGroup
ProxyForGroup method asynchronousCallOnGroup() can be made to lock both this and any other ProxyForGroup object Complicated state required to produce this scenario Setup code spans 23 lines, with 11 objects created, and 6 methods invoked Some cases are quite subtle, including the asynchronousCallOnGroup() method in ProActive. In the proper state, this method descends into four nested levels of control flow and calls a method that returns a ProxyForGroup, which is later locked and can result in deadlock.

75 Cyclic Deadlocks java.util.Vector can be deadlocked by forming a cycle with two Vector instances Similar deadlock in All other synchronized Collections Combinations of those Collections This deadlock only counted once for JDK and Classpath 5 other deadlocks Vector v1, v2; Object o; v1.add(v2); v2.add(v1); Thread 1: v1.contains(o); locks v1, v2 Thread 2: v2.contains(o); locks v2, v1 v1 v2 The Vector contains() method and the equals() method can both be deadlocked when in this cyclic state.

76 Resolving Deadlocks Two possible solutions: Issue: must know locks
Rewrite methods to acquire locks in set order Extend Java with synchronization primitive to atomically acquire multiple locks (can also write this as a library method) Issue: must know locks Can sometimes write helper methods to determine locks Locks may change while being determined Global lock or transactions are alternatives Acquiring multiple locks can be done by ordering the locks using System.identityHashCode(), breaking ties arbitrarily but consistently.

77 Outline Introduction Deadlock Detection Algorithm Results
Related Work and Conclusions

78 Related Work Using lock-order graphs: RacerX [Engler, Ashcraft 2003]
Jlint [Artho, Biere 2001]; von Praun 2004 For programs, do not detect all deadlocks RacerX [Engler, Ashcraft 2003] Non-hierarchical locking (for C), requires annotations, does not detect all deadlocks Model Checking: Demartini, Iosif, Sisto 1999 Java Pathfinder: Havelund, Pressburger 2000 For programs, not scalable Ownership Types: Boyapati, Lee, Rinard 2002 Requires annotations, restricts programming model

79 Conclusions Our analysis is effective at
Verifying libraries to be free from deadlock Finding deadlocks Analysis of libraries can be effective at finding library specific defects

80

81 Sources of Imprecision
Consider infeasible aliasing / sharing across threads Do not track flow of values through fields Consider infeasible paths of control


Download ppt "Static Deadlock Detection for Java Libraries"

Similar presentations


Ads by Google