FULLY AUTOMATIC AND PRECISE DETECTION OF THREAD SAFETY VIOLATIONS

Similar documents
Fully Automatic and Precise Detection of Thread Safety Violations

Automatic Testing of Sequential and Concurrent Substitutability

Synchronization SPL/2010 SPL/20 1

Runtime Atomicity Analysis of Multi-threaded Programs

CalFuzzer: An Extensible Active Testing Framework for Concurrent Programs Pallavi Joshi 1, Mayur Naik 2, Chang-Seo Park 1, and Koushik Sen 1

Leveraging Test Generation and Specification Mining for Automated Bug Detection without False Positives

Index COPYRIGHTED MATERIAL

C16b: Exception Handling

Training topic: OCPJP (Oracle certified professional Java programmer) or SCJP (Sun certified Java programmer) Content and Objectives

Randomized Active Atomicity Violation Detection in Concurrent Programs

Problems with Concurrency

ITI Introduction to Computing II

Fork Sequential Consistency is Blocking

CS4215 Programming Language Implementation. Martin Henz

ITI Introduction to Computing II

Exception in thread "main" java.lang.arithmeticexception: / by zero at DefaultExceptionHandling.main(DefaultExceptionHandling.

Programmazione di sistemi multicore

AP COMPUTER SCIENCE JAVA CONCEPTS IV: RESERVED WORDS

Fork Sequential Consistency is Blocking

3.Constructors and Destructors. Develop cpp program to implement constructor and destructor.

CSC Java Programming, Fall Java Data Types and Control Constructs

Pages and 68 in [JN] conventions for using exceptions in Java. Chapter 8 in [EJ] guidelines for more effective use of exceptions.

Aspect-Oriented Programming for Guided Testing. SiyuanLiua, Yang Yangb

Java Array List Interview Questions

Concurrent Objects and Linearizability

A Schedulability-Preserving Transformation Scheme from Boolean- Controlled Dataflow Networks to Petri Nets

RACE CONDITIONS AND SYNCHRONIZATION

Introduction to Locks. Intrinsic Locks

Active Testing for Concurrent Programs

1/16/2013. Program Structure. Language Basics. Selection/Iteration Statements. Useful Java Classes. Text/File Input and Output.

Sharing Objects Ch. 3

CS 351 Design of Large Programs Programming Abstractions

Performance Throughput Utilization of system resources

Practical Concurrency. Copyright 2007 SpringSource. Copying, publishing or distributing without express written permission is prohibited.

Information System Design (IT60105)

Java Exception. Wang Yang

Chapter 32 Multithreading and Parallel Programming

Indexing and Searching

Chapter 13 Exception Handling

The Sun s Java Certification and its Possible Role in the Joint Teaching Material

Problems with Concurrency. February 19, 2014

Ohad Barzilay and Oranit Dror

Exception Handling Advanced Programming Techniques

CS180 Review. Recitation Week 15

Operational Semantics. One-Slide Summary. Lecture Outline

Harvard School of Engineering and Applied Sciences CS 152: Programming Languages

Introduction to Visual Basic and Visual C++ Introduction to Java. JDK Editions. Overview. Lesson 13. Overview

simplicity hides complexity flow of control, negation, cut, 2 nd order programming, tail recursion procedural and declarative semantics and & or

ECE 122. Engineering Problem Solving with Java

Basics of Java: Expressions & Statements. Nathaniel Osgood CMPT 858 February 15, 2011

Active Testing for Concurrent Programs

Brief Summary of Java

Basic Principles of analysis and testing software

Building Efficient Concurrent Graph Object through Composition of List-based Set

Joint Entity Resolution

Functional Programming in Haskell Part I : Basics

Concurrent Libraries with Foresight

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

Lecture 4: Procedure Specifications

Heuristics-based Parameter Generation for Java Methods

Shin Hwei Tan Darko Marinov Lin Tan Gary T. Leavens University of Illinois. University of Illinois

COE318 Lecture Notes Week 10 (Nov 7, 2011)

9/21/17. Outline. Expression Evaluation and Control Flow. Arithmetic Expressions. Operators. Operators. Notation & Placement

The SPIN Model Checker

For more details on SUN Certifications, visit

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

Overview of Lecture 4. Memory Models, Atomicity & Performance. Ben-Ari Concurrency Model. Dekker s Algorithm 4

Predicting Null-Pointer Dereferences in Concurrent Programs. Parthasarathy Madhusudan Niloofar Razavi Francesco Sorrentino

CSE332: Data Abstractions Lecture 23: Programming with Locks and Critical Sections. Tyler Robison Summer 2010

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

CSE 374 Programming Concepts & Tools

DynaMoth: Dynamic Code Synthesis for Automatic Program Repair

Reinhard v. Hanxleden 1, Michael Mendler 2, J. Aguado 2, Björn Duderstadt 1, Insa Fuhrmann 1, Christian Motika 1, Stephen Mercer 3 and Owen Brian 3

Log System Based on Software Testing System Design And Implementation

Subclassing for ADTs Implementation

Distributed Systems. Rik Sarkar James Cheney Global State & Distributed Debugging February 3, 2014

Lecture Outline. COOL operational semantics. Operational Semantics of Cool. Motivation. Notation. The rules. Evaluation Rules So Far.

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

Operational Semantics of Cool

CS 160: Interactive Programming

Types, Values and Variables (Chapter 4, JLS)

Enhancing The Fault-Tolerance of Nonmasking Programs

Lecture 5: Declarative Programming. The Declarative Kernel Language Machine. September 12th, 2011

COMP 213. Advanced Object-oriented Programming. Lecture 17. Exceptions

A Third Look At Java. Chapter Seventeen Modern Programming Languages, 2nd ed. 1

CIS265 - Spring Exam 2 First Name Last Name CSU#

Primitive Data and Objects

Finding Concurrency Bugs in Java

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

CFix. Automated Concurrency-Bug Fixing. Guoliang Jin, Wei Zhang, Dongdong Deng, Ben Liblit, and Shan Lu. University of Wisconsin Madison

Building Java Programs

Transactum Business Process Manager with High-Performance Elastic Scaling. November 2011 Ivan Klianev

Classes, interfaces, & documentation. Review of basic building blocks

The Java Memory Model

15CS45 : OBJECT ORIENTED CONCEPTS

Thread Safety. Review. Today o Confinement o Threadsafe datatypes Required reading. Concurrency Wrapper Collections

1.00 Lecture 29. Sensors and Threads. Reading for next time: Numerical Recipes (online)

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

Guidelines for Writing C Code

Generating Code from Event-B Using an Intermediate Specification Notation

Transcription:

FULLY AUTOMATIC AND PRECISE DETECTION OF THREAD SAFETY VIOLATIONS PLDI 2012 by Michael Pradel and Thomas R. Gross ETH Zurich presented by Martin Aigner University of Salzburg May 2, 2013

OVERVIEW The problem of testing multi-threaded code Proposed solution: automatically generate test cases Evaluation of the results

TESTING FOR THREAD-SAFETY Consider a (wanna-be thread-safe) class in an OO language... Try to argue about it s thread-safety... How do you do that? Verify correct concurrent behavior? Too expensive in most cases Write tests? How? Where to start? Where to end? Also expensive

EXAMPLE class StringBuffer implements CharSequence { /* init instance with given string */ StringBuffer(String s) {...} /* modify this holding a lock */ synchronized void deletecharat (int index) {...} /* modify this while holding a lock */ synchronized void insert (int dstoffset, CharSequence s, int start, int end) {...} } /* convenience overloading */ void insert (int dstoffset, CharSequence s) { this.insert(dstoffset, s, 0, s.length()); }

class StringBuffer implements CharSequence { /* init instance with given string */ StringBuffer(String s) {...} /* modify this holding a lock */ synchronized void deletecharat (int index) {...} /* modify this while holding a lock */ synchronized void insert (int dstoffset, CharSequence s, int start, int end) {...} } /* convenience overloading */ void insert (int dstoffset, CharSequence s) { this.insert(dstoffset, s, 0, s.length()); } main: StringBuffer sb1 = new StringBuffer( thread-safe ); main: StringBuffer sb2 = new StringBuffer( not ); Thread 1 Thread 2 sb1.insert(0, sb2); sb1.deletecharat(0); Result?

class StringBuffer implements CharSequence { /* init instance with given string */ StringBuffer(String s) {...} /* modify this holding a lock */ synchronized void deletecharat (int index) {...} /* modify this while holding a lock */ synchronized void insert (int dstoffset, CharSequence s, int start, int end) {...} } /* convenience overloading */ void insert (int dstoffset, CharSequence s) { this.insert(dstoffset, s, 0, s.length()); } main: StringBuffer sb1 = new StringBuffer( thread-safe ); Thread 1 Thread 2 sb1.insert(0, sb1); sb1.deletecharat(0); Result?

PROBLEMS WITH TESTING In general: Cover the configuration space Observe success of failure For concurrent tests: Find out if a concurrent execution meets a sequential specification

PROPOSED SOLUTION Create, execute, and validate test cases automatically

REQUIREMENTS We need: The class under test (CUT) A set of auxiliary classes the CUT depends on A test that maybe triggers a bug (thread-safety violation) An execution environment that exposes the bug An oracle that recognizes an erroneous execution

GENERATING CONCURRENT TESTS Definitions: call sequence, prefix, suffixes A call sequence is a n-tuple of calls (c1,..., cn) where a call is a method together with input and output parameters Prefix: a call sequence that is executed sequentially to grow an object Suffixes: a set of call sequences that are executed concurrently on an object to trigger a concurrency bug

GENERATING CONCURRENT TESTS Definitions: test A test is a triple (p, s1, s2) where p is a prefix and s1 and s2 are suffixes p1 pn s11 s21 s1j s2k

EXAMPLE: CONCURRENT TEST prefix p main: StringBuffer sb1 = new StringBuffer( thread-safe ); Thread 1 Thread 2 sb1.insert(0, sb1); sb1.deletecharat(0); suffix s1 suffix s2

TASKS: CREATING CALL SEQUENCES A task takes a call sequence sin = (c1,..., ci) and returns a call sequence sout = (c1,..., ci, cj,..., cn) 3 types of tasks: instantiatecuttask: appends a call to instantiate the CUT callcuttask: appends a call to the CUT instance parametertask: provides a typed parameter by either: selecting a previous output parameter appending a call that returns the parameter

TEST GENERATION ALGORITHM Three global variables: P: a set of prefixes M: a map assigning a prefix to its set of suffixes T: a set of already generated tests

TEST GENERATION ALGORITHM Step 1: create a new prefix invokes instantiatecuttask to create an instance of CUT repeatedly invokes callcuttask to extend the prefix the parametertask is invoked whenever a call requires a parameter

TEST GENERATION ALGORITHM Step 2: create a suffix for a prefix repeatedly invokes callcuttask and use the output parameters of the prefix as input the suffix again, the parametertask is invoked whenever a call requires a parameter add the suffix to M for the given prefix

TEST GENERATION ALGORITHM Step 3: test creation create tests based on the prefix, the suffix and all it s other suffixes (obtained from M) and store them in T randomly return a test from T

Algorithm 1 Returns a concurrent test (p, s 1,s 2 ) 1: P: set of prefixes B global variables 2: M: maps a prefix to suffixes 3: T : set of ready-to-use tests 4: if T > 0 then 5: return randremove(t ) 6: if P <maxprefixesthen B create a new prefix 7: p instantiatecut T ask(empty call sequence) 8: if p = failed then 9: if P = ; then 10: fail( cannot instantiate CUT ) 11: else 12: p randtake(p) 13: else 14: for i 1,maxStateChangerTriesdo 15: p ext callcut T ask(p) 16: if p ext 6= failed then 17: p p ext 18: P P [ {p} 19: else 20: p randtake(p) 21: s 1 empty call sequence B create a new suffix 22: for i 1,maxCUTCallTriesdo 23: s 1,ext callcut T ask(s 1,p) 24: if s 1,ext 6= failed then 25: s 1 s 1,ext 26: M(p) M(p) [ {s 1 } 27: for all s 2 2 M(p) do B one test for each pair of suffixes 28: T T [ {(p, s 1,s 2 )} 29: return randremove(t ) Step 1 Step 2 Step 3 the parameters maxprefixes, maxstatechangertries and maxcutcalltries are heuristically defined limits.

THREAD SAFETY ORACLE A class is said to be thread-safe (in Java methodology) if: multiple threads can use it without synchronization and the observed behavior of a concurrent execution is equivalent to and sequential execution of a linearization of the calls preserving per-thread ordering

EXAMPLE main: CopyOnWriteArrayList l = new CopyOnWriteArrayList(); Thread 1 Thread 2 l.add( a ); l.add( b ); println(l.tostring()); Results: [a], [a,b], or [b,a] Linearizations: add( a );! println();! add( b ); gives [a] add( a );! add( b );! println(); gives [a, b] add( b );! add( a );! println(); gives [b, a]

DEFINITIONS operator concatenates call sequences For calls c and c, the notion c c indicates that call c precedes c

LINEARIZATION Definition 1 (Linearization). For a test (p, s 1,s 2 ), let P 12 be the set of all permutations of the call sequence s 1 s 2. The set of linearizations of the test is: L (p,s1,s 2 ) = {p s 12 s 12 2 P 12 ^ (8c, c 0 (c! s1 c 0 ) c! s12 c 0 ) ^ (c! s2 c 0 ) c! s12 c 0 ))} That is, a linearization of a test appends to all calls Intuitively: a linearization of a test (p, s1, s2) appends to p all calls from s1 and from s2 in a way that preserves the order of calls in s1 and s2

EXECUTION Definition 2 (Execution). For a test (p, s 1,s 2 ), we denote the set of all distinguishable executions of this test as E (p,s1,s 2 ). Each e (p,s1,s 2 ) 2 E (p,s1,s 2 ) represents the sequential execution of p followed by a concurrent execution of s 1 and s 2. Likewise, we denote the sequential execution of a call sequence s as e s. Note: due to the non-determinism of concurrent executions a single test can have multiple distinguishable executions

THREAD SAFETY Notation: for executions e1 and e2, the notion e1 e2 indicates that e1 and e2 are equivalent (discussed later) Definition 3 (Thread safety). Let T C be the set of all possible tests for a class C. C is thread-safe if and only if: 8(p, s 1,s 2 ) 2 T C 8e (p,s1,s 2 ) 2 E (p,s1,s 2 ) 9l 2 L (p,s1,s 2 ) so that e (p,s1,s 2 ) = e l That is, a class is thread-safe if each concurrent test execution

THREAD SAFETY Notation: for executions e1 and e2, the notion e1 e2 indicates that e1 and e2 are equivalent (discussed later) Definition 3 (Thread safety). Let T C be the set of all possible tests for a class C. C is thread-safe if and only if: 8(p, s 1,s 2 ) 2 T C 8e (p,s1,s 2 ) 2 E (p,s1,s 2 ) 9l 2 L (p,s1,s 2 ) so that e (p,s1,s 2 ) = e l That is, a class is thread-safe if each concurrent test execution Problem: this is expensive! All executions times all tests times all linearizations... Let s try the opposite

THREAD-UNSAFETY We call a class thread-unsafe if: 9(p, s 1,s 2 ) 2 T C 9e (p,s1,s 2 ) 2 E (p,s1,s 2 ) so that 8l 2 L (p,s1,s 2 ) e (p,s1,s 2 ) e l Intuitively: the oracle tries to find a test that exposes behavior not possible with any linearization of the test Still expensive, but we are lucky this time. We only need to check buggy concurrent executions for equivalence to their linearizations

EQUIVALENCE OF EXECUTION Definition 4 (Equivalence of executions). Two executions e 1 and e 2 are equivalent if neither e 1 nor e 2 results in an exception or a deadlock, or both e 1 and e 2 fail for the same reason (that is, the same type of exception is thrown or both executions end with a deadlock).

Algorithm 2 Checks whether a test (p, s 1,s 2 ) exposes a thread safety bug 1: repeat consider only failed 2: e (p,s1,s 2 ) execute(p, s 1,s 2 ) concurrent executions 3: if failed(e (p,s1,s )) then 2 4: seqf ailed false no concurrency bug if 5: for all l 2 L(p, s 1,s 2 ) do linearization fails for the 6: if seqf ailed = false then same reason 7: e l execute(l) 8: if failed(e l ) ^ samef ailure(e (p,s1,s ),e 2 l ) then 9: seqf ailed true 10: concurrency bug only if if seqf ailed = false then 11: the linearizations did not report bug e (p,s1,s 2 ) and exit 12: until maxconcexecs reached fail

LIMITATIONS Only exceptions and deadlocks are considered Testing is still incomplete No semantical equivalence of concurrent and linearized executions The proposed approach is based on two assumptions: Uncaught exceptions and deadlocks that occur in concurrent executions but not in sequential ones are a problem Sequential execution is deterministic

CONTRIBUTIONS Fully automatic Only true positives are reported No (or very little) human effort for testing and evaluation This makes it cheap! It does indeed find bugs

EVALUATION Tests were performed on six popular code bases Java standard library Apache Commons DBCP XStream (serialization library) LingPipe (text processing toolkit) JFreeChart (chart library) Joda-Time (library for handling data and time)

ID Code base Class Declared Found Reason for failing Implicit thread-safe unsafe Previously unknown bugs: (1) JDK 1.6.0 27 and 1.7.0 StringBuffer yes yes IndexOutOfBoundsException yes (2) JDK 1.6.0 27 and 1.7.0 ConcurrentHashMap yes yes StackOverflowError yes (3) Commons DBCP 1.4 SharedPoolDataSource yes yes ConcurrentModificationException yes (4) Commons DBCP 1.4 PerUserPoolDataSource yes yes ConcurrentModificationException yes (5) XStream 1.4.1 XStream yes yes NullPointerException yes (6) LingPipe 4.1.0 MedlineSentenceModel yes yes IllegalStateException no Known bugs: (7) JDK 1.1 BufferedInputStream yes yes NullPointerException yes (8) JDK 1.4.1 Logger yes yes NullPointerException yes (9) JDK 1.4.2 SynchronizedMap yes yes Deadlock yes (10) JFreeChart 0.9.8 TimeSeries yes yes NullPointerException yes (11) JFreeChart 0.9.8 XYSeries yes yes ConcurrentModificationException yes (12) JFreeChart 0.9.12 NumberAxis yes yes IllegalArgumentException no (13) JFreeChart 1.0.1 PeriodAxis yes yes IllegalArgumentException no (14) JFreeChart 1.0.9 XYPlot yes yes ConcurrentModificationException yes (15) JFreeChart 1.0.13 Day yes yes NumberFormatException yes Automatic classification of classes as thread-unsafe: (16) Joda-Time 2.0 DateTimeFormatterBuilder no yes IndexOutOfBoundsException (10x) yes (17) Joda-Time 2.0 DateTimeParserBucket no yes IllegalArgumentException (9x) no NullPointerException (1x) yes (18) Joda-Time 2.0 DateTimeZoneBuilder no yes NullPointerException (6x) yes ArrayIndexOutOfBoundsException (2x) yes IllegalFieldValueException (2x) yes (19) Joda-Time 2.0 MutableDateTime no yes IllegalFieldValueException (9x) no ArithmeticException (1x) yes (20) Joda-Time 2.0 MutableInterval no yes IllegalArgumentException (10x) no (21) Joda-Time 2.0 MutablePeriod no yes ArithmeticException (10x) yes (22) Joda-Time 2.0 PeriodFormatterBuilder no yes ConcurrentModificationException (5x) yes IndexOutOfBoundsException (4x) yes IllegalStateException (1x) no Joda-Time 2.0 ZoneInfoCompiler no no (stopped after 24h)

COSTS on 8-core 3GHz Xeons Time (min/avg/max minutes) 1000 100 10 1 0.1 0.01 > 1 hour < 1 minute 11 7 16 22 13 10 15 12 20 17 21 18 6 14 1 9 2 19 3 5 4 8 CUTs (sorted by avg. time) (a) Time to trigger a thread-safety problem.

1e+08 REQUIRED TEST CASES Generated tests (avg.) 1e+07 1e+06 100000 10000 1000 100 10 11 7 16 22 13 10 15 12 20 17 21 18 6 14 1 9 2 19 3 5 4 8 CUTs (sorted by avg. time) (b) Tests generated before triggering a thread-safety problem.

REFERENCE Michael Pradel and Thomas R. Gross. 2012. Fully automatic and precise detection of thread safety violations. In Proceedings of the 33rd ACM SIGPLAN conference on Programming Language Design and Implementation (PLDI '12). ACM, New York, NY, USA, 521-530.

THANKS A LOT