static deadlock detection for java libraries
play

Static Deadlock Detection for Java Libraries Amy Williams , William - PowerPoint PPT Presentation

Static Deadlock Detection for Java Libraries Amy Williams , William Thies, and Michael D. Ernst Massachusetts Institute of Technology Deadlock Each deadlocked thread attempts to acquire a lock held by another thread Can halt entire


  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: Thread 2: a.append(b); b.append(a); b locks a, b locks b, a

  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

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

  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); Thread 1: Thread 2: support.propertyChange(event); support.remove(source); locks global, field locks field, global Also found 13 other deadlocks

  6. Analysis Overview 1. Build lock-order graph representing locking behavior of each method in library 2. Combine graphs for all public methods into single graph 3. 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; Object public boolean remove(Object targetChild) { synchronized(BeanContext.globalHierarchyLock) { ... synchronized(children) { HashMap children.remove(targetChild); } ... } ... } Continued...

  8. JDK Source (simplified), cont. class BeanContextSupport { protected HashMap children; public void propertyChange(PropertyChangeEvent pce) { ... Object source = pce.getSource(); Object synchronized(children) { if (...) { ... remove(source); 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 Object deadlock – Expose cases in which threads lock set of locks in different HashMap (conflicting) orders

  10. Outline • Introduction • Deadlock Detection Algorithm • Results • Related Work and Conclusions

  11. Synchronization in Java • Locking is hierarchical, performed using synchronized statement synchronized (lock1) { synchronized (lock2) { – 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

  12. Synchronization in Java • wait() and notify() methods described in paper • 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 1. Build lock-order graph representing locking behavior of each method in library • Callee graphs integrated into caller • Iterate to fixed point; termination guaranteed 2. Combine graphs for all public methods into single graph 3. 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 set 1 methods to be combined • Edges mean the source lock set 2 set 3 held while destination lock acquired • Cycles indicate possibility of deadlock

  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); } }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend