Effective Static Deadlock Detection Mayur Naik (Intel Research) Chang-Seo Park and Koushik Sen (UC Berkeley) David Gay (Intel Research)

Slides:



Advertisements
Similar presentations
Dataflow Analysis for Datarace-Free Programs (ESOP 11) Arnab De Joint work with Deepak DSouza and Rupesh Nasre Indian Institute of Science, Bangalore.
Advertisements

A Technique for Parallel Reachability Analysis of Java Programs Raghuraman R. Sridhar Iyer G. Sajith.
A Randomized Dynamic Program Analysis for Detecting Real Deadlocks Pallavi Joshi  Chang-Seo Park  Koushik Sen  Mayur Naik ‡  Par Lab, EECS, UC Berkeley‡
Effective Static Deadlock Detection
1 Chao Wang, Yu Yang*, Aarti Gupta, and Ganesh Gopalakrishnan* NEC Laboratories America, Princeton, NJ * University of Utah, Salt Lake City, UT Dynamic.
Deadlock Prevention, Avoidance, and Detection
Compilation 2011 Static Analysis Johnni Winther Michael I. Schwartzbach Aarhus University.
Pointer Analysis – Part I Mayur Naik Intel Research, Berkeley CS294 Lecture March 17, 2009.
Conditional Must Not Aliasing for Static Race Detection Mayur Naik Alex Aiken Stanford University.
Verification of Multithreaded Object- Oriented Programs with Invariants Bart Jacobs, K. Rustan M. Leino, Wolfram Schulte.
A Randomized Dynamic Program Analysis for Detecting Real Deadlocks Koushik Sen CS 265.
Scalable and Precise Dynamic Datarace Detection for Structured Parallelism Raghavan RamanJisheng ZhaoVivek Sarkar Rice University June 13, 2012 Martin.
1 Symbolic Execution for Model Checking and Testing Corina Păsăreanu (Kestrel) Joint work with Sarfraz Khurshid (MIT) and Willem Visser (RIACS)
Guoliang Jin, Linhai Song, Wei Zhang, Shan Lu, and Ben Liblit University of Wisconsin–Madison Automated Atomicity- Violation Fixing.
1 Concurrency Specification. 2 Outline 4 Issues in concurrent systems 4 Programming language support for concurrency 4 Concurrency analysis - A specification.
Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)
CS 263 Course Project1 Survey: Type Systems for Race Detection and Atomicity Feng Zhou, 12/3/2003.
ADVERSARIAL MEMORY FOR DETECTING DESTRUCTIVE RACES Cormac Flanagan & Stephen Freund UC Santa Cruz Williams College PLDI 2010 Slides by Michelle Goodstein.
Progress Guarantee for Parallel Programs via Bounded Lock-Freedom Erez Petrank – Technion Madanlal Musuvathi- Microsoft Bjarne Steensgaard - Microsoft.
C. FlanaganSAS’04: Type Inference Against Races1 Type Inference Against Races Cormac Flanagan UC Santa Cruz Stephen N. Freund Williams College.
Establishing Local Temporal Heap Safety Properties with Applications to Compile-Time Memory Management Ran Shaham Eran Yahav Elliot Kolodner Mooly Sagiv.
Mayur Naik Alex Aiken John Whaley Stanford University Effective Static Race Detection for Java.
1 RELAY: Static Race Detection on Millions of Lines of Code Jan Voung, Ranjit Jhala, and Sorin Lerner UC San Diego speaker.
1 A Modular Checker for Multithreaded Programs Cormac Flanagan HP Systems Research Center Joint work with Shaz Qadeer Sanjit A. Seshia.
Cormac Flanagan UC Santa Cruz Velodrome: A Sound and Complete Dynamic Atomicity Checker for Multithreaded Programs Jaeheon Yi UC Santa Cruz Stephen Freund.
Formal Verification of SpecC Programs using Predicate Abstraction Himanshu Jain Daniel Kroening Edmund Clarke Carnegie Mellon University.
Memory Management for Real-Time Java Wes Beebee and Martin Rinard Laboratory for Computer Science Massachusetts Institute of Technology Supported by: DARPA.
Threads in Java1 Concurrency Synchronizing threads, thread pools, etc.
University of Michigan Electrical Engineering and Computer Science 1 Practical Lock/Unlock Pairing for Concurrent Programs Hyoun Kyu Cho 1, Yin Wang 2,
Impact Analysis of Database Schema Changes Andy Maule, Wolfgang Emmerich and David S. Rosenblum London Software Systems Dept. of Computer Science, University.
Thread-modular Abstraction Refinement Thomas A. Henzinger, et al. CAV 2003 Seonggun Kim KAIST CS750b.
Testing Concurrent Programs COMP Production Programming Mathias Ricken Rice University Spring 2009.
Mining Windows Kernel API Rules Jinlin Yang 09/28/2005CS696.
Finding Optimum Abstractions in Parametric Dataflow Analysis Xin Zhang Georgia Tech Mayur Naik Georgia Tech Hongseok Yang University of Oxford.
1 Effective Static Race Detection for Java Mayur, Alex, CS Department Stanford University Presented by Roy Ganor 14/2/08 Point-To Analysis Seminar.
Deadlock Detection Nov 26, 2012 CS 8803 FPL 1. Part I Static Deadlock Detection Reference: Effective Static Deadlock Detection [ICSE’09]
/ PSWLAB Type-Based Race Detection for J AVA by Cormac Flanagan, Stephen N. Freund 22 nd Feb 2008 presented by Hong,Shin Type-Based.
1 Processes, Threads, Race Conditions & Deadlocks Operating Systems Review.
Pallavi Joshi* Mayur Naik † Koushik Sen* David Gay ‡ *UC Berkeley † Intel Labs Berkeley ‡ Google Inc.
Games Development 2 Concurrent Programming CO3301 Week 9.
DoubleChecker: Efficient Sound and Precise Atomicity Checking Swarnendu Biswas, Jipeng Huang, Aritra Sengupta, and Michael D. Bond The Ohio State University.
Multithreading in JAVA
ESEC/FSE-99 1 Data-Flow Analysis of Program Fragments Atanas Rountev 1 Barbara G. Ryder 1 William Landi 2 1 Department of Computer Science, Rutgers University.
The ATOMOS Transactional Programming Language Mehdi Amirijoo Linköpings universitet.
Dataflow Analysis for Concurrent Programs using Datarace Detection Ravi Chugh, Jan W. Voung, Ranjit Jhala, Sorin Lerner LBA Reading Group Michelle Goodstein.
Michael Bond Katherine Coons Kathryn McKinley University of Texas at Austin.
Motivation  Parallel programming is difficult  Culprit: Non-determinism Interleaving of parallel threads But required to harness parallelism  Sequential.
CS265: Dynamic Partial Order Reduction Koushik Sen UC Berkeley.
Threads and Singleton. Threads  The JVM allows multiple “threads of execution”  Essentially separate programs running concurrently in one memory space.
Effective Static Deadlock Detection Mayur Naik* Chang-Seo Park +, Koushik Sen +, David Gay* *Intel Research, Berkeley + UC Berkeley.
Deadlock Bug Detection Techniques Prof. Moonzoo Kim CS KAIST CS492B Analysis of Concurrent Programs 1.
Comunication&Synchronization threads 1 Programación Concurrente Benemérita Universidad Autónoma de Puebla Facultad de Ciencias de la Computación Comunicación.
Pointer Analysis – Part I CS Pointer Analysis Answers which pointers can point to which memory locations at run-time Central to many program optimization.
D A C U C P Speculative Alias Analysis for Executable Code Manel Fernández and Roger Espasa Computer Architecture Department Universitat Politècnica de.
/ PSWLAB Thread Modular Model Checking by Cormac Flanagan and Shaz Qadeer (published in Spin’03) Hong,Shin Thread Modular Model.
Verifying Component Substitutability Nishant Sinha Sagar Chaki Edmund Clarke Natasha Sharygina Carnegie Mellon University.
Concurrency (Threads) Threads allow you to do tasks in parallel. In an unthreaded program, you code is executed procedurally from start to finish. In a.
Where Testing Fails …. Problem Areas Stack Overflow Race Conditions Deadlock Timing Reentrancy.
Effective Static Race Detection for Java Mayur Naik Alex Aiken Stanford University.
A User-Guided Approach to Program Analysis Ravi Mangal, Xin Zhang, Mayur Naik Georgia Tech Aditya Nori Microsoft Research.
Jeremy Nimmer, page 1 Automatic Generation of Program Specifications Jeremy Nimmer MIT Lab for Computer Science Joint work with.
Making k-Object-Sensitive Pointer Analysis More Precise with Still k-Limiting Tian Tan, Yue Li and Jingling Xue SAS 2016 September,
Healing Data Races On-The-Fly
Amir Kamil and Katherine Yelick
Concurrency Specification
Over-Approximating Boolean Programs with Unbounded Thread Creation
Amir Kamil and Katherine Yelick
Threads and Multithreading
Foundations and Definitions
Presentation transcript:

Effective Static Deadlock Detection Mayur Naik (Intel Research) Chang-Seo Park and Koushik Sen (UC Berkeley) David Gay (Intel Research)

What is a Deadlock? An unintended condition in a shared-memory, multi-threaded program in which: –a set of threads blocks forever –because each thread in the set waits to acquire a lock being held by another thread in the set This talk: ignore other causes (e.g., wait/notify) Example // thread t1 sync (l1) { sync (l2) { … } // thread t2 sync (l2) { sync (l1) { … } l1 t1 l2 t2

Motivation Today’s concurrent programs are rife with deadlocks –6,500/198,000 (~ 3%) of bug reports in Sun’s bug database at are deadlocks Deadlocks are difficult to detect –Usually triggered non-deterministically, on specific thread schedules –Fail-stop behavior not guaranteed (some threads may be deadlocked while others continue to run) Fixing other concurrency bugs like races can introduce new deadlocks –Our past experience with reporting races: developers often ask for deadlock checker

Previous Work Based on detecting cycles in program’s dynamic or static lock order graph Dynamic approaches –Inherently unsound –Inapplicable to open programs –Can be ineffective without sufficient test input data Static approaches –Type systems Annotation burden often significant –Model checking Does not currently scale beyond few KLOC –Dataflow analysis Scalable but highly imprecise l1 t1 l2 t2

Deadlock freedom is a complex property –can t1,t2 denote different threads? –can l1,l4 denote same lock? –can t1 acquire locks l1->l2? –some more … Challenges to Static Deadlock Detection l = abstract lock acq. t = abstract thread t1 l1 l2 t1 l1 l2 t2 l4 l3 t2

Deadlock freedom is a complex property –can t1,t2 denote different threads? –can l1,l4 denote same lock? –can t1 acquire locks l1->l2? –some more … Existing static deadlock checkers cannot check all conditions simultaneously and effectively But each condition can be checked separately and effectively using existing static analyses Our Rationale t1 l1 l2 t1 l1 l2 t2 l4 l3 t2

may-reach(t1,l1,l2)? may-alias(l1,l4)? Consider all candidate deadlocks in closed program Check each of six necessary conditions for each candidate to be a deadlock Report candidates that satisfy all six conditions Note: Finds only deadlocks involving 2 threads/locks –Deadlocks involving > 2 threads/locks rare in practice Our Approach l1 l2 t1 l4 l3 t2 t1 l1 l2 t2...

Example: jdk1.4 java.util.logging class LogManager { static LogManager manager = new LogManager(); 155: Hashtable loggers = new Hashtable(); 280: sync boolean addLogger(Logger l) { String name = l.getName(); if (!loggers.put(name, l)) return false; // ensure l’s parents are instantiated for (...) { String pname =...; 314: Logger.getLogger(pname); } return true; } 420: sync Logger getLogger(String name) { return (Logger) loggers.get(name); } } class Logger { 226: static sync Logger getLogger(String name) { LogManager lm = LogManager.manager; 228: Logger l = lm.getLogger(name); if (l == null) { l = new Logger(...); 231: lm.addLogger(l); } return l; } } class Harness { static void main(String[] args) { 11: new Thread() { void run() { 13: Logger.getLogger(...); }}.start(); 16: new Thread() { void run() { 18: LogManager.manager.addLogger(...); }}.start(); } } t1 t2 l4 l2 l3 l1

Example Deadlock Report *** Stack trace of thread : LogManager.addLogger (LogManager.java:280) - this allocated at - waiting to lock { } Logger.getLogger (Logger.java:231) - holds lock { } Harness$1.run (Harness.java:13) *** Stack trace of thread : Logger.getLogger (Logger.java:226) - waiting to lock { } LogManager.addLogger (LogManager.java:314) - this allocated at - holds lock { } Harness$2.run (Harness.java:18)

Our Approach Six necessary conditions identified experimentally Checked using four incomplete but sound whole- program static analyses 1.Reachable 2.Aliasing 3.Escaping 4.Parallel 5.Non-reentrant 6.Non-guarded 1.Call-graph analysis 2.May-alias analysis 3.Thread-escape analysis 4.May-happen-in-parallel analysis Relatively language independent Incomplete but sound checks } } Widely-used Java locking idioms Incomplete and unsound checks - sound needs must-alias analysis

Precision of call-graph and may-alias analyses is central –Directly used to check certain conditions –Other two static analyses also use them We use k-object-sensitive combined call-graph and may-alias analysis –Invented by Milanova et al. [ISSTA 2003] –Both context-sensitive and object-sensitive Necessary for precise reasoning about locks –Much more precise than k-CFA k-Object-Sensitivity

Property: In some execution: –can a thread abstracted by t1 reach l1 –and after acquiring lock at l1, proceed to reach l2 while holding that lock? –and similarly for t2, l3, l4 Solution: Use call-graph analysis Condition 1: Reachable t1 l1 l2 t1 l1 l2 l4 l3 t2 l4 l3 t2

Example: jdk1.4 java.util.logging class LogManager { static LogManager manager = new LogManager(); 155: Hashtable loggers = new Hashtable(); 280: sync boolean addLogger(Logger l) { String name = l.getName(); if (!loggers.put(name, l)) return false; // ensure l’s parents are instantiated for (...) { String pname =...; 314: Logger.getLogger(pname); } return true; } 420: sync Logger getLogger(String name) { return (Logger) loggers.get(name); } class Logger { 226: static sync Logger getLogger(String name) { LogManager lm = LogManager.manager; 228: Logger l = lm.getLogger(name); if (l == null) { l = new Logger(...); 231: lm.addLogger(l); } return l; } class Harness { static void main(String[] args) { 11: new Thread() { void run() { 13: Logger.getLogger(...); }}.start(); 16: new Thread() { void run() { 18: LogManager.manager.addLogger(...); }}.start(); } t1 t2 l4 l2 l3 l1

Condition 2: Aliasing Property: In some execution: –can a lock acquired at l1 be the same as a lock acquired at l4? –and similarly for l2, l3 Solution: Use may-alias analysis l1 l2 t1 l1 l2 l4 l3 t2

Example: jdk1.4 java.util.logging class LogManager { static LogManager manager = new LogManager(); 155: Hashtable loggers = new Hashtable(); 280: sync boolean addLogger(Logger l) { String name = l.getName(); if (!loggers.put(name, l)) return false; // ensure l’s parents are instantiated for (...) { String pname =...; 314: Logger.getLogger(pname); } return true; } 420: sync Logger getLogger(String name) { return (Logger) loggers.get(name); } class Logger { 226: static sync Logger getLogger(String name) { LogManager lm = LogManager.manager; 228: Logger l = lm.getLogger(name); if (l == null) { l = new Logger(...); 231: lm.addLogger(l); } return l; } class Harness { static void main(String[] args) { 11: new Thread() { void run() { 13: Logger.getLogger(...); }}.start(); 16: new Thread() { void run() { 18: LogManager.manager.addLogger(...); }}.start(); } t1 t2 l4 l2 l3 l1

Condition 3: Escaping Property: In some execution: –can a lock acquired at l1 be thread-shared? –and similarly for each of l2, l3, l4 Solution: Use thread-escape analysis l1 l2 t1 l1 l2 l4 l3 l4 l3 t2

Example: jdk1.4 java.util.logging class LogManager { static LogManager manager = new LogManager(); 155: Hashtable loggers = new Hashtable(); 280: sync boolean addLogger(Logger l) { String name = l.getName(); if (!loggers.put(name, l)) return false; // ensure l’s parents are instantiated for (...) { String pname =...; 314: Logger.getLogger(pname); } return true; } 420: sync Logger getLogger(String name) { return (Logger) loggers.get(name); } class Logger { 226: static sync Logger getLogger(String name) { LogManager lm = LogManager.manager; 228: Logger l = lm.getLogger(name); if (l == null) { l = new Logger(...); 231: lm.addLogger(l); } return l; } class Harness { static void main(String[] args) { 11: new Thread() { void run() { 13: Logger.getLogger(...); }}.start(); 16: new Thread() { void run() { 18: LogManager.manager.addLogger(...); }}.start(); } t1 t2 l4 l2 l3 l1

Condition 4: Parallel Property: In some execution: –can different threads abstracted by t1 and t2 –simultaneously reach l2 and l4? Solution: Use may-happen-in-parallel analysis –Does not model full happens-before relation –Models only thread fork construct –Other conditions model other constructs ≠ t1 l1 l2 t1 l1 l2 l4 l3 t2 l4 l3 t2

Example: jdk1.4 java.util.logging class LogManager { static LogManager manager = new LogManager(); 155: Hashtable loggers = new Hashtable(); 280: sync boolean addLogger(Logger l) { String name = l.getName(); if (!loggers.put(name, l)) return false; // ensure l’s parents are instantiated for (...) { String pname =...; 314: Logger.getLogger(pname); } return true; } 420: sync Logger getLogger(String name) { return (Logger) loggers.get(name); } class Logger { 226: static sync Logger getLogger(String name) { LogManager lm = LogManager.manager; 228: Logger l = lm.getLogger(name); if (l == null) { l = new Logger(...); 231: lm.addLogger(l); } return l; } class Harness { static void main(String[] args) { 11: new Thread() { void run() { 13: Logger.getLogger(...); }}.start(); 16: new Thread() { void run() { 18: LogManager.manager.addLogger(...); }}.start(); } t1 t2 l4 l2 l3 l1

Condition 5: Non-reentrant Property: In some execution: –can a thread abstracted by t1 acquire a non-reentrant lock at l1 –and, while holding that lock, proceed to acquire a non- reentrant lock at l2? –and similarly for t2, l3, l4 Solution: Use call-graph + may-alias analysis –Unsound: Needs must-alias analysis ≠≠ t1 l1 l2 t1 l1 l2 l4 l3 t2 l4 l3 t2

Example: jdk1.4 java.util.logging class LogManager { static LogManager manager = new LogManager(); 155: Hashtable loggers = new Hashtable(); 280: sync boolean addLogger(Logger l) { String name = l.getName(); if (!loggers.put(name, l)) return false; // ensure l’s parents are instantiated for (...) { String pname =...; 314: Logger.getLogger(pname); } return true; } 420: sync Logger getLogger(String name) { return (Logger) loggers.get(name); } class Logger { 226: static sync Logger getLogger(String name) { LogManager lm = LogManager.manager; 228: Logger l = lm.getLogger(name); if (l == null) { l = new Logger(...); 231: lm.addLogger(l); } return l; } class Harness { static void main(String[] args) { 11: new Thread() { void run() { 13: Logger.getLogger(...); }}.start(); 16: new Thread() { void run() { 18: LogManager.manager.addLogger(...); }}.start(); } t1 t2 l4 l2 l3 l1

Condition 6: Non-guarded Property: In some execution: –can different threads abstracted by t1 and t2 reach l1 and l3, respectively, without holding a common lock? Solution: Use call-graph + may-alias analysis –Unsound: Needs must-alias analysis lg t1 l1 l2 t1 l1 l2 l4 l3 t2 l4 l3 t2

Example: jdk1.4 java.util.logging class LogManager { static LogManager manager = new LogManager(); 155: Hashtable loggers = new Hashtable(); 280: sync boolean addLogger(Logger l) { String name = l.getName(); if (!loggers.put(name, l)) return false; // ensure l’s parents are instantiated for (...) { String pname =...; 314: Logger.getLogger(pname); } return true; } 420: sync Logger getLogger(String name) { return (Logger) loggers.get(name); } class Logger { 226: static sync Logger getLogger(String name) { LogManager lm = LogManager.manager; 228: Logger l = lm.getLogger(name); if (l == null) { l = new Logger(...); 231: lm.addLogger(l); } return l; } class Harness { static void main(String[] args) { 11: new Thread() { void run() { 13: Logger.getLogger(...); }}.start(); 16: new Thread() { void run() { 18: LogManager.manager.addLogger(...); }}.start(); } t1 t2 l4 l2 l3 l1

BenchmarkLOCClassesMethodsSyncsTime moldyn31, m48s montecarlo157, m53s raytracer32, m51s tsp154, m48s sor32, m48s hedc160, m15s weblech184, m02s jspider159, m34s jigsaw154, m23s ftp180, m55s dbcp168, m04s cache4j34, m43s logging167, m01s collections38, m42s Benchmarks

BenchmarkDeadlocks (0-cfa) Deadlocks (k-obj.) Lock type pairs (total) Lock type pairs (real) moldyn0000 montecarlo0000 raytracer0000 tsp0000 sor0000 hedc7,5522, weblech4, jspider jigsaw ftp16,2593, dbcp cache4j0000 logging4, collections Experimental Results

Individual Analysis Contributions

Conclusion Novel approach to static deadlock detection for Java –Checks six necessary conditions for a deadlock –Uses four off-the-shelf static analyses Neither sound nor complete, but effective in practice –Applied to suite of 14 multi-threaded Java programs comprising over 1.5 MLOC –Found all known deadlocks as well as previously unknown ones, with few false alarms