Static Deadlock Detection for Java Libraries

Similar documents
Master of Science in Computer Science. at the. June A uthor... Department of Electrical Engineering and Computer Science May 20, 2005

Computing Approximate Happens-Before Order with Static and Dynamic Analysis

Chapter 5 Asynchronous Concurrent Execution

Effective Static Deadlock Detection

Fully Automatic and Precise Detection of Thread Safety Violations

A Parameterized Type System for Race-Free Java Programs

Synchronization SPL/2010 SPL/20 1

Automated Inference of Atomic Sets for Safe Concurrent Execution

Java for Programmers Course (equivalent to SL 275) 36 Contact Hours

The Java Memory Model

Programmazione di sistemi multicore

Process Synchronisation (contd.) Deadlock. Operating Systems. Spring CS5212

Non-blocking Array-based Algorithms for Stacks and Queues. Niloufar Shafiei

Deadlock Bug Detection Techniques

MultiJav: A Distributed Shared Memory System Based on Multiple Java Virtual Machines. MultiJav: Introduction

CMSC 330: Organization of Programming Languages

Detection of Deadlock Potentials in Multi-Threaded Programs

Runtime Atomicity Analysis of Multi-threaded Programs

Core Java - SCJP. Q2Technologies, Rajajinagar. Course content

Chapter 5 Concurrency: Mutual Exclusion. and. Synchronization. Operating Systems: Internals. and. Design Principles

Thin Locks: Featherweight Synchronization for Java

5/23/2015. Core Java Syllabus. VikRam ShaRma

Advanced Threads & Monitor-Style Programming 1/24

Automatic Testing of Sequential and Concurrent Substitutability

Chapter 32 Multithreading and Parallel Programming

W4118: concurrency error. Instructor: Junfeng Yang

Java 8 Programming for OO Experienced Developers

The New Java Technology Memory Model

Testing Concurrent Java Programs Using Randomized Scheduling

CS 160: Interactive Programming

CSE332: Data Abstractions Lecture 19: Mutual Exclusion and Locking

MULTITHREADING has become a common programming

CMSC 433 Programming Language Technologies and Paradigms. Composing Objects

AP COMPUTER SCIENCE JAVA CONCEPTS IV: RESERVED WORDS

SSC - Concurrency and Multi-threading Java multithreading programming - Synchronisation (II)

Sharing Objects Ch. 3

Duet: Static Analysis for Unbounded Parallelism

CS 455: INTRODUCTION TO DISTRIBUTED SYSTEMS [THREADS] Frequently asked questions from the previous class survey

C. Flanagan Dynamic Analysis for Atomicity 1

Concurrency and Recovery

Atomicity. Experience with Calvin. Tools for Checking Atomicity. Tools for Checking Atomicity. Tools for Checking Atomicity

Ownership, Encapsulation and the Disjointness of Type and Effect. Dave Clarke Utrecht University Sophia Drossopoulou Imperial College, London

JavaSplit. A Portable Distributed Runtime for Java. Michael Factor Assaf Schuster Konstantin Shagin

A Sophomoric Introduction to Shared-Memory Parallelism and Concurrency Lecture 5 Programming with Locks and Critical Sections

Synchronized Methods of Old Versions of Java

Types for Precise Thread Interference

Effec%ve Sta%c Deadlock Detec%on

Need for synchronization: If threads comprise parts of our software systems, then they must communicate.

Multi-threading in Java. Jeff HUANG

A Sophomoric Introduction to Shared-Memory Parallelism and Concurrency Lecture 4 Shared-Memory Concurrency & Mutual Exclusion

Chapter 6 Introduction to Defining Classes

CSE 332: Locks and Deadlocks. Richard Anderson, Steve Seitz Winter 2014

CS 2112 Lecture 20 Synchronization 5 April 2012 Lecturer: Andrew Myers

Module 6: Process Synchronization. Operating System Concepts with Java 8 th Edition

10/17/ Gribble, Lazowska, Levy, Zahorjan 2. 10/17/ Gribble, Lazowska, Levy, Zahorjan 4

Java Threads and intrinsic locks

Modular Reasoning about Aliasing using Permissions

Objects and Aspects: Ownership Types

FastTrack: Efficient and Precise Dynamic Race Detection (+ identifying destructive races)

CMSC 330: Organization of Programming Languages

Interactive Refinement of Hierarchical Object Graphs

Operating Systems. Synchronization

Chapter 6: Synchronization. Operating System Concepts 8 th Edition,

Concurrency, Mutual Exclusion and Synchronization C H A P T E R 5

CMSC 132: Object-Oriented Programming II

Ownership Types. Fabian Muehlboeck. April 11, 2012

Static Analysis for Safe Concurrency

Homework #10 due Monday, April 16, 10:00 PM

CS/ENGRD2110: Final Exam

1 Shyam sir JAVA Notes

7/6/2015. Motivation & examples Threads, shared memory, & synchronization. Imperative programs

11/19/2013. Imperative programs

Heap Order Property: Key stored at the parent is smaller or equal to the key stored at either child.

Multitasking Multitasking allows several activities to occur concurrently on the computer. A distinction is usually made between: Process-based multit

Programmazione di sistemi multicore

Motivation & examples Threads, shared memory, & synchronization

Atomicity for Reliable Concurrent Software. Race Conditions. Motivations for Atomicity. Race Conditions. Race Conditions. 1. Beyond Race Conditions

Randomized Active Atomicity Violation Detection in Concurrent Programs

Chapter 5 Concurrency: Mutual Exclusion and Synchronization

G Programming Languages Spring 2010 Lecture 13. Robert Grimm, New York University

A Causality-Based Runtime Check for (Rollback) Atomicity

Lecture 10 State dependency

CSE 332: Data Structures & Parallelism Lecture 18: Race Conditions & Deadlock. Ruth Anderson Autumn 2017

Code verification. CSE 331 University of Washington. Michael Ernst

Chapter 6: Process Synchronization. Module 6: Process Synchronization

Parallel Code Smells: A Top 10 List

Toward Efficient Strong Memory Model Support for the Java Platform via Hybrid Synchronization

Making Context-sensitive Points-to Analysis with Heap Cloning Practical For The Real World

Threading and Synchronization. Fahd Albinali

Finding Errors in Multithreaded GUI Applications

Applications of Paxos Algorithm

Static Conflict Analysis for Multi-Threaded Object Oriented Programs

Computation Abstractions. Processes vs. Threads. So, What Is a Thread? CMSC 433 Programming Language Technologies and Paradigms Spring 2007

Chapter 4 Java Language Fundamentals

Midterm Exam Amy Murphy 6 March 2002

David Glasser Michael D. Ernst CSAIL, MIT

Index. Course Outline. Grading Policy. Lab Time Distribution. Important Instructions

Compiler Techniques For Memory Consistency Models

From IMP to Java. Andreas Lochbihler. parts based on work by Gerwin Klein and Tobias Nipkow ETH Zurich

Object and Reference Immutability using Java Generics

Transcription:

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 program execution Difficult to expose during testing Once exposed, difficult to replicate Example: StringBuffer a, b; a Thread 1: a.append(b); locks a, b Thread 2: b.append(a); locks b, a b

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

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

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

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

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); Continued Object HashMap

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) {

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

Outline Introduction Deadlock Detection Algorithm Results Related Work and Conclusions

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

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

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

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 set 1 Edges mean the source lock set 2 held while destination lock acquired Cycles indicate possibility of deadlock set 3

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

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: []

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: []

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: b1 No locks held, so node is root Ordered list of locks held: [b1]

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: b1 Ordered list of locks held: [b1]

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: b1 c1 Ordered list of locks held: [b1, c1]

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: b1 c1 Ordered list of locks held: [b1, c1]

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: b1 c1 Ordered list of locks held: [b1]

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

Example Analysis: openaccount() 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: [] deposit s graph: b1 c1

Example Analysis: openaccount() 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: b2 Ordered list of locks held: [b2] deposit s graph: b1 c1

Example Analysis: openaccount() 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: c2 b2 Ordered list of locks held: [c2] deposit s graph: b1 c1

Example Analysis: openaccount() 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: c2 b2 Ordered list of locks held: [c2] deposit s graph: b1 c1

Example Analysis: openaccount() 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: current graph: c2 Ordered list of locks held: [c2] b2 deposit s graph: b1 c1

Call to deposit(): update copy of 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); b2 Graph: current graph: c2 b1 b2 c1 Ordered list of locks held: [c2] b2 deposit s graph: b1 c1

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); c2 Graph: c2 b2 c1 c2 Ordered list of locks held: [c2] b2 b1 c1

Call to deposit(): update copy of 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: current graph: c2 b2 c2 Ordered list of locks held: [c2] b2 deposit s graph: b1 c1

Call to deposit(): update copy of 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: b2 current graph: c2 b2 Ordered list of locks held: [c2] b2 deposit s graph: b1 c1

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: c2 b2 b2 Ordered list of locks held: [c2] deposit s graph: b1 c1

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: c2 b2 b2 Ordered list of locks held: [c2] deposit s graph: b1 c1

Lock-order graph for openaccount() 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: c2 deposit s graph: b2 b1 c1

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

Combine Graphs Graph for deposit(): Graph for openaccount(): b1 c2 b2 c1

Combine Graphs Graph for deposit(): Graph for openaccount(): Bank Client Bank Client

Combine Graphs Graph for deposit(): Graph for openaccount(): Final graph: Bank Client Bank Client

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

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

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

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 99 reports to only 1 Context-sensitivity (integrating callee graphs) greatly improved precision

Outline Introduction Deadlock Detection Algorithm Results Related Work and Conclusions

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

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

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

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

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

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

Non-verified Libraries Library sync kloc Reports Deadlocks Found JDK 1458 419 Out of Memory 7 Classpath 754 295 Out of Memory 5 ProActive 199 63 196 2 Jess 111 27 269 sdsu 69 26 2,479 Deadlocked JVM for all 14 cases

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

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

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

Deadlocks Found BeanContextSupport StringBuffer synchronized Collections PrintWriter/CharArrayWriter java.awt.dnd.droptarget java.awt.eventqueue java.awt.menu java.util.simpletimezone java.util.logging.logger JDK Classpath ProActive: ProxyForGroup, AbstractDataObject

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

Cyclic Deadlocks java.util.vector can be deadlocked by forming a cycle with two Vector instances v1 v2 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 Similar deadlock in All other synchronized Collections Combinations of those Collections This deadlock only counted once for JDK and Classpath 5 other deadlocks

Outline Introduction Deadlock Detection Algorithm Results Related Work and Conclusions

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

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

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

Resolving Deadlocks Two possible solutions: 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