Deadlock Detection Nov 26, 2012 CS 8803 FPL 1. Part I Static Deadlock Detection Reference: Effective Static Deadlock Detection [ICSE’09]

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 Randomized Dynamic Program Analysis for Detecting Real Deadlocks Pallavi Joshi  Chang-Seo Park  Koushik Sen  Mayur Naik ‡  Par Lab, EECS, UC Berkeley‡
CS 267: Automated Verification Lecture 8: Automata Theoretic Model Checking Instructor: Tevfik Bultan.
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.
Runtime Verification Ali Akkaya Boğaziçi University.
Abstraction and Modular Reasoning for the Verification of Software Corina Pasareanu NASA Ames Research Center.
Conditional Must Not Aliasing for Static Race Detection Mayur Naik Alex Aiken Stanford University.
Goldilocks: Efficiently Computing the Happens-Before Relation Using Locksets Tayfun Elmas 1, Shaz Qadeer 2, Serdar Tasiran 1 1 Koç University, İstanbul,
Concurrency Important and difficult (Ada slides copied from Ed Schonberg)
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.
Guoliang Jin, Linhai Song, Wei Zhang, Shan Lu, and Ben Liblit University of Wisconsin–Madison Automated Atomicity- Violation Fixing.
/ PSWLAB Concurrent Bug Patterns and How to Test Them by Eitan Farchi, Yarden Nir, Shmuel Ur published in the proceedings of IPDPS’03 (PADTAD2003)
1 Concurrency Specification. 2 Outline 4 Issues in concurrent systems 4 Programming language support for concurrency 4 Concurrency analysis - A specification.
Monitors Chapter 7. The semaphore is a low-level primitive because it is unstructured. If we were to build a large system using semaphores alone, the.
Atomicity in Multi-Threaded Programs Prachi Tiwari University of California, Santa Cruz CMPS 203 Programming Languages, Fall 2004.
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.
C. FlanaganSAS’04: Type Inference Against Races1 Type Inference Against Races Cormac Flanagan UC Santa Cruz Stephen N. Freund Williams College.
Mayur Naik Alex Aiken John Whaley Stanford University Effective Static Race Detection for Java.
Modular Verification of Multithreaded Software Shaz Qadeer Compaq Systems Research Center Shaz Qadeer Compaq Systems Research Center Joint work with Cormac.
Exceptions and side-effects in atomic blocks Tim Harris.
Michael Ernst, page 1 Improving Test Suites via Operational Abstraction Michael Ernst MIT Lab for Computer Science Joint.
Synchronization in Java Fawzi Emad Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
1 Organization of Programming Languages-Cheng (Fall 2004) Concurrency u A PROCESS or THREAD:is a potentially-active execution context. Classic von Neumann.
Cormac Flanagan UC Santa Cruz Velodrome: A Sound and Complete Dynamic Atomicity Checker for Multithreaded Programs Jaeheon Yi UC Santa Cruz Stephen Freund.
Memory Management for Real-Time Java Wes Beebee and Martin Rinard Laboratory for Computer Science Massachusetts Institute of Technology Supported by: DARPA.
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.
Unit Testing & Defensive Programming. F-22 Raptor Fighter.
XFindBugs: eXtended FindBugs for AspectJ Haihao Shen, Sai Zhang, Jianjun Zhao, Jianhong Fang, Shiyuan Yao Software Theory and Practice Group (STAP) Shanghai.
Mining Windows Kernel API Rules Jinlin Yang 09/28/2005CS696.
Accelerating Precise Race Detection Using Commercially-Available Hardware Transactional Memory Support Serdar Tasiran Koc University, Istanbul, Turkey.
1 Effective Static Race Detection for Java Mayur, Alex, CS Department Stanford University Presented by Roy Ganor 14/2/08 Point-To Analysis Seminar.
/ 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.
Deadlock Analysis with Fewer False Positives Thread T1: sync(G){ sync(L1){ sync(L2){} } }; T3 = new T3(); j3.start(); J3.join(); sync(L2){ sync(L1){} }
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.
CS533 – Spring Jeanie M. Schwenk Experiences and Processes and Monitors with Mesa What is Mesa? “Mesa is a strongly typed, block structured programming.
CMSC 330: Organization of Programming Languages Threads.
Effective Static Deadlock Detection Mayur Naik* Chang-Seo Park +, Koushik Sen +, David Gay* *Intel Research, Berkeley + UC Berkeley.
CAPP: Change-Aware Preemption Prioritization Vilas Jagannath, Qingzhou Luo, Darko Marinov Sep 6 th 2011.
Deadlock Bug Detection Techniques Prof. Moonzoo Kim CS KAIST CS492B Analysis of Concurrent Programs 1.
Grigore Rosu Founder, President and CEO Professor of Computer Science, University of Illinois
Comunication&Synchronization threads 1 Programación Concurrente Benemérita Universidad Autónoma de Puebla Facultad de Ciencias de la Computación Comunicación.
Effective Static Deadlock Detection Mayur Naik (Intel Research) Chang-Seo Park and Koushik Sen (UC Berkeley) David Gay (Intel Research)
/ PSWLAB Thread Modular Model Checking by Cormac Flanagan and Shaz Qadeer (published in Spin’03) Hong,Shin Thread Modular Model.
Specifying Multithreaded Java semantics for Program Verification Abhik Roychoudhury National University of Singapore (Joint work with Tulika Mitra)
Reachability Testing of Concurrent Programs1 Reachability Testing of Concurrent Programs Richard Carver, GMU Yu Lei, UTA.
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.
Testing Concurrent Programs Sri Teja Basava Arpit Sud CSCI 5535: Fundamentals of Programming Languages University of Colorado at Boulder Spring 2010.
Where Testing Fails …. Problem Areas Stack Overflow Race Conditions Deadlock Timing Reentrancy.
Effective Static Race Detection for Java Mayur Naik Alex Aiken Stanford University.
Jeremy Nimmer, page 1 Automatic Generation of Program Specifications Jeremy Nimmer MIT Lab for Computer Science Joint work with.
Healing Data Races On-The-Fly
runtime verification Brief Overview Grigore Rosu
Specifying Multithreaded Java semantics for Program Verification
Threads Chate Patanothai.
Concurrency Specification
Monitors Chapter 7.
Over-Approximating Boolean Programs with Unbounded Thread Creation
Background and Motivation
Monitors Chapter 7.
Synchronization and liveness
Presentation transcript:

Deadlock Detection Nov 26, 2012 CS 8803 FPL 1

Part I Static Deadlock Detection Reference: Effective Static Deadlock Detection [ICSE’09]

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 work: ignore other causes (e.g., wait/notify) Example // Thread t1 sync (l1) { sync (l2) { … } // Thread t2 sync (l2) { sync (l1) { … } l1 t1 l2 t2 What is a Deadlock?

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 Motivation

Based on finding cycles in program’s dynamic or static lock order graph Dynamic approaches –Inherently unsound –Inapplicable to open programs –Ineffective without sufficient test input data Static approaches –Type systems (e.g., Boyapati-Lee-Rinard OOPSLA’02) Annotation burden often significant –Model checking (e.g., SPIN) Does not currently scale beyond few KLOC –Dataflow analysis (e.g., Engler & Ashcraft SOSP’03; Williams-Thies-Ernst ECOOP’05) Scalable but highly imprecise l1 t1 l2 t2 Previous Work

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 … l = abstract lock acq. t = abstract thread t1 l1 l2 t1 l1 l2 t2 l4 l3 t2 Challenges to Static Deadlock Detection

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 … t1 l1 l2 t1 l1 l2 t2 l4 l3 t2 Our Rationale

t1 l1 l2 t1 l1 l2 t2 l4 l3 t2 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

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 l1 l2 t1 l4 l3 t2 t1 l1 l2 t2... Our Approach may-reach(t1,l1,l2)? may-alias(l1,l4)?

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: jdk1.4 java.util.logging

*** 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) Example Deadlock Report

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 Our Approach

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 –k-object-sensitive [Milanova-Rountev-Ryder ISSTA ’ 03] t1 l1 l2 t1 l1 l2 l4 l3 t2 l4 l3 t2 Condition 1: Reachable

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: jdk1.4 java.util.logging

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 –k-object-sensitive [Milanova-Rountev-Ryder ISSTA ’ 03] l1 l2 t1 l1 l2 l4 l3 t2 Condition 2: Aliasing

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: jdk1.4 java.util.logging

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 Condition 3: Escaping

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: jdk1.4 java.util.logging

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 Condition 4: Parallel

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: jdk1.4 java.util.logging

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

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 Conclusion

Part II Dynamic Deadlock Detection Reference: An Effective Dynamic Analysis Technique for Detecting Generalized Deadlocks [FSE’10]

Motivation Most previous deadlock detection work has focused on resource deadlocks Example // Thread T1 // Thread T2 sync(L1) { sync(L2) { sync(L2) { sync(L1) { …. …. } } L1 T1 L2 T2

Motivation Other kinds of deadlocks, e.g. communication deadlocks, are equally notorious Example // Thread T1 // Thread T2 if (!b) { b = true; sync(L) { sync(L) { L.wait(); L.notify(); } } } T2T1 if(!b) wait L b = true notify L b is initially false

Goal Build a dynamic analysis based tool that: –detects communication deadlocks –scales to large programs –has low false positive rate

Our Initial Effort Take cue from existing dynamic analyses for other concurrency errors Existing dynamic analyses check for violation of a programming idiom –Races: every shared variable is consistently protected by a lock –Resource deadlocks: no cycle in lock ordering graph –Atomicity violations: atomic blocks should have the pattern (R+B)*N(L+B)*

Our Initial Effort What programming idiom should we check for communication deadlocks?

Our Initial Effort Recommended usage of condition variables // Thread T1 // Thread T2 sync (L) { sync (L) { while (!cond) cond = true; L.wait(); L.notifyAll(); assert (cond == true); } }

An Example Recommended usage of condition variables // Thread T1 // Thread T2 sync (L) { sync (L) { while (list.isEmpty()) list.add(...); L.wait(); L.notifyAll(); … = list.remove(); } }

Violation of Idiom as Deadlock Example // Thread T1 // Thread T2 if (!b) b = true; sync (L) L.notifyAll(); sync (L) L.wait(); Must use while, not if Accesses to b must be inside sync

Satisfaction of Idiom as Deadlock Example // Thread T1 // Thread T2 sync (L1) sync (L2) while (!b) L2.wait(); sync (L1) sync (L2) L2.notifyAll(); => Recommended usage pattern (or idiom) based checking does not work No violation of idiom, but still deadlocks!

Revisiting Existing Analyses Relax the dependencies between relevant events from different threads –verify all possible event orderings for errors –use data structures to check idioms (vector clocks, lock- graphs etc.) to implicitly verify all event orderings

Revisiting Existing Analyses Programming idiom-based checking does not work for communication deadlocks Nevertheless, we can explicitly verify all orderings of relevant events for deadlocks

Trace Program // Thread T1 // Thread T2 if (!b) { b = true; sync (L) { sync (L) { L.wait (); L.notify (); } } } b is initially false lock L wait L unlock L lock L unlock L notify L T1T2

Trace Program lock L wait L unlock L lock L unlock L notify L T1T2 Thread T1 { lock L; wait L; unlock L; } Thread T2 { lock L; notify L; unlock L; }

Trace Program Thread T1 {Thread T2 { lock L; lock L; wait L; || notify L; unlock L; } lock L wait L unlock L lock L unlock L notify L T1T2

Trace Program Built out of only a subset of events –usually much smaller than the original program Throws away a lot of dependencies between threads –could give false positives –but increases coverage

// Thread T1 // Thread T2 if (!b) { b = true; sync (L) { sync (L) { L.wait (); L.notify (); } } } b is initially false lock L wait L unlock L lock L unlock L notify L T1T2 if (!b) b = true Trace Program: Add Dependencies

lock L wait L unlock L lock L unlock L notify L T1T2 if (!b) b = true Thread T1 { if (!b) { lock L; wait L; unlock L; } Thread T2 { b = true; lock L; notify L; unlock L; } Trace Program: Add Dependencies

Trace Program: Add Predictivity Use static analysis to add to the predictive power of the trace program // Thread T1 // Thread !b => L.wait() if (!b) { b = true; sync (L) { sync (L) { L.wait (); L.notify (); } } } b is initially false Thread T1 { if (!b) { lock L; wait L; unlock L; }

Effective for concurrency errors that cannot be detected using a programming idiom –communication deadlocks, deadlocks due of exceptions, … // Thread T1 // Thread T2 while (!b) { try { sync (L) { foo(); L.wait(); b = true; } sync (L) { L.notify(); } } } catch (Exception e) {…} b is initially false can throw an exception Trace Program: Other Errors

Implemented for deadlock detection –both communication and resource deadlocks Built a prototype tool for Java called CHECKMATE Applied to several Java libraries and applications –log4j, pool, felix, lucene, jgroups, jruby.... Found both previously known and unknown deadlocks (17 in total) Implementation and Evaluation

Conclusion CHECKMATE is a novel dynamic analysis for finding deadlocks –both resource and communication deadlocks Effective on several real-world Java benchmarks Trace program based approach is generic –can be applied to other errors, e.g. deadlocks because of exceptions

Did Not Cover Today … Deadlock Detection in Message-Passing Programs –must model many variants of message sends/receives Dynamic Deadlock Avoidance –unique to deadlock errors (cannot, e.g., “avoid” buffer overruns) –see Dimmunix OSDI’08 paper ( Dynamic Deadlock Detection by Controlling Thread Schedules –CHESS ( –CalFuzzer ( Type-based Deadlock Detection –statically check lock-order graph (see OOPSLA’02 paper)