54
Guided Test Visualization: Making Sense of Errors in Concurrent Programs Saint Wesonga & Neha Rungta & Eric Mercer Brigham Young University & NASA AMES, USA

Guided Test Visualization : Making Sense of Errors in Concurrent Programs

  • Upload
    apollo

  • View
    50

  • Download
    0

Embed Size (px)

DESCRIPTION

Guided Test Visualization : Making Sense of Errors in Concurrent Programs . Saint Wesonga & Neha Rungta & Eric Mercer Brigham Young University & NASA AMES, USA. State of the Art. Stress Testing Dynamic Analysis Runtime monitoring Static Analysis Model Checking Symbolic Execution - PowerPoint PPT Presentation

Citation preview

Page 1: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Guided Test Visualization: Making Sense of Errors in

Concurrent Programs Saint Wesonga & Neha Rungta & Eric Mercer Brigham Young University & NASA AMES, USA

Page 2: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

State of the Art Stress Testing Dynamic Analysis Runtime monitoring Static Analysis Model Checking Symbolic Execution Software Model Checking

Guided-test [SPIN 2009]Slice And Dice [ICSE-NIER

2010]

Page 3: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Belief

Sea of choices

Guided by belief

Guided-test and Slice-and-dice

Page 4: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Guided-test wants to find real errors

Find an error or you do not have much to say

Not intended to be exhaustive

Thus not complete

Yet sound

Page 5: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Our SolutionPossible errorslocations from

imprecise analysis tools

Generate backward

slicesfrom

possibleerror

locationsRuntime

Environment

Sound error

detection

Add inter-thread dependenceinformation

Heuristics

Guided Symbolic Execution

Page 6: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

InputPossible errorslocations from

imprecise analysis tools

Generate backward

slicesfrom

possibleerror

locationsRuntime

Environment

Sound error

detection

Add inter-thread dependenceinformation

Heuristics

Guided Symbolic Execution

Page 7: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Small exampleThread A {

void run (Element elem) { lock(elem)

check(elem)unlock(elem)

}

void check(Element elem) {if(elem.e > 9)

Throw exception

}}

Thread B {void run (Element elem) {

int x; // input variable

if( x > 18) {

lock(elem)

elem.reset();

unlock(elem)}

}}Object Element {

int e;Element() { e = 1;

}

void reset() {e = 11;

}}

Page 8: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Small ExampleThread A {

void run (Element elem) { lock(elem)

check(elem)unlock(elem)

}

void check(Element elem) {if(elem.e > 9)

Throw exception

}}

Thread B {void run (Element elem) {

int x; // input variable

if( x > 18) {

lock(elem)

elem.reset();

unlock(elem)}

}}Object Element {

int e;Element() { e = 1;

}

void reset() {e = 11;

}}

Page 9: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Small ExampleThread A {

void run (Element elem) { lock(elem)

check(elem)unlock(elem)

}

void check(Element elem) {if(elem.e > 9)

Throw exception

}}

Thread B {void run (Element elem) {

int x; // input variable

if( x > 18) {

lock(elem)

elem.reset();

unlock(elem)}

}}Object Element {

int e;Element() { e = 1;

}

void reset() {e = 11;

}}

Page 10: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Small ExampleThread A {

void run (Element elem) { lock(elem)

check(elem)unlock(elem)

}

void check(Element elem) {if(elem.e > 9)

Throw exception

}}

Thread B {void run (Element elem) {

int x; // input variable

if( x > 18) {

lock(elem)

elem.reset();

unlock(elem)}

}}Object Element {

int e;Element() { e = 1;

}

void reset() {e = 11;

}}

Page 11: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Small ExampleThread A {

void run (Element elem) { lock(elem)

check(elem)unlock(elem)

}

void check(Element elem) {if(elem.e > 9)

Throw exception

}}

Thread B {void run (Element elem) {

int x; // input variable

if( x > 18) {

lock(elem)

elem.reset();

unlock(elem)}

}}Object Element {

int e;Element() { e = 1;

}

void reset() {e = 11;

}}

Page 12: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Small ExampleThread A {

void run (Element elem) { lock(elem)

check(elem)unlock(elem)

}

void check(Element elem) {if(elem.e > 9)

Throw exception

}}

Thread B {void run (Element elem) {

int x; // input variable

if( x > 18) {

lock(elem)

elem.reset();

unlock(elem)}

}}Object Element {

int e;Element() { e = 1;

}

void reset() {e = 11;

}}

Page 13: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Small ExampleThread A {

void run (Element elem) { lock(elem)

check(elem)unlock(elem)

}

void check(Element elem) {if(elem.e > 9)

Throw exception

}}

Thread B {void run (Element elem) {

int x; // input variable

if( x > 18) {

lock(elem)

elem.reset();

unlock(elem)}

}}Object Element {

int e;Element() { e = 1;

}

void reset() {e = 11;

}}

Page 14: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Could it really be?Thread A {

void run (Element elem) { lock(elem)

check(elem)unlock(elem)

}

void check(Element elem) {if(elem.e > 9)

Throw exception

}}

Thread B {void run (Element elem) {

int x; // input variable

if( x > 18) {

lock(elem)

elem.reset();

unlock(elem)}

}}Object Element {

int e;Element() { e = 1;

}

void reset() {e = 11;

}}

Is it possible to arrive at this location on some

execution?

Page 15: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Initial Abstraction to Follow (not explore)

Possible errorslocations from

imprecise analysis tools

Generate backward

slicesto possible

error locations

Runtime Environment

Sound error

detection

Add inter-thread dependenceinformation

Heuristics

Guided Symbolic Execution

Page 16: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Slice along sequential executionThread A {

void run (Element elem) { lock(elem)

check(elem)unlock(elem)

}

void check(Element elem) {if(elem.e > 9)

Throw exception

}} Object Element {

int e;Element() { e = 1;

}

void reset() {e = 11;

}}

Page 17: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Target Locations & Start of ProgramsA.run lstart

Exception

Thread A {void run (Element elem) {

lock(elem)

check(elem)unlock(elem)

}

void check(Element elem) {if(elem.e > 9)

Throw exception

}} Object Element {

int e;Element() { e = 1;

}

void reset() {e = 11;

}}

Page 18: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Call Sites and Start Locs of the calleeA.run lstart

check(elem)

A.check lstart

Exception

Object Element { int e;

Element() { e = 1;

}

void reset() {e = 11;

}}

Thread A {void run (Element elem) {

lock(elem)

check(elem)unlock(elem)

}

void check(Element elem) {if(elem.e > 9)

Throw exception

}}

Page 19: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Conditional StatementsA.run lstart

check(elem)

A.check lstart

if(elem.e > 9)

Exception

Thread A {void run (Element elem) {

lock(elem)

check(elem)unlock(elem)

}

void check(Element elem) {if(elem.e > 9)

Throw exception

}} Object Element {

int e;Element() { e = 1;

}

void reset() {e = 11;

}}

Page 20: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Data DefinitionsA.run lstart

check(elem)

A.check lstart

if(elem.e > 9)

Exception

Thread A {void run (Element elem) {

lock(elem)

check(elem)unlock(elem)

}

void check(Element elem) {if(elem.e > 9)

Throw exception

}} Object Element {

int e;Element() { e = 1;

}

void reset() {e = 11;

}}

Page 21: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Synchronization OperationsA.run lstart

lock(elem)

check(elem)

unlock(elem) A.check lstart

if(elem.e > 9)

Exception

Thread A {void run (Element elem) {

lock(elem)

check(elem)unlock(elem)

}

void check(Element elem) {if(elem.e > 9)

Throw exception

}} Object Element {

int e;Element() { e = 1;

}

void reset() {e = 11;

}}

Page 22: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Abstract SystemA.run lstart

lock(elem)

check(elem)

unlock(elem) A.check lstart

if(elem.e > 9)

Exception

Thread A {void run (Element elem) {

lock(elem)

check(elem)unlock(elem)

}

void check(Element elem) {if(elem.e > 9)

Throw exception

}} Object Element {

int e;Element() { e = 1;

}

void reset() {e = 11;

}}

Page 23: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Abstract TraceA.run lstart

lock(elem)

check(elem)

unlock(elem) A.check lstart

if(elem.e > 9)

Exception

Thread A {void run (Element elem) {

lock(elem)

check(elem)unlock(elem)

}

void check(Element elem) {if(elem.e > 9)

Throw exception

}} Object Element {

int e;Element() { e = 1;

}

void reset() {e = 11;

}}

Page 24: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Abstract TraceA.run lstart

lock(elem)

check(elem)

A.check lstart

if(elem.e > 9)

Exception

Thread A {void run (Element elem) {

lock(elem)

check(elem)unlock(elem)

}

void check(Element elem) {if(elem.e > 9)

Throw exception

}} Object Element {

int e;Element() { e = 1;

}

void reset() {e = 11;

}}

One trace of many we could have selected: fair coin or

farm in parallel

Page 25: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Our SolutionPossible errorslocations from

imprecise analysis tools

Generate backward

slicesto possible

error locations

Runtime Environment

Sound error

detection

Add inter-thread dependenceinformation

Heuristics

Guided Symbolic Execution

Page 26: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Extract current program location of the

most recently executed thread

Map Concrete state to a location

Thread-0

StackLocalVars

Thread-1

StackLocalVars

Thread-n

StackLocalVars

HeapGlobalVars

Data Input VariablesSymbolic Representations

ϕpath Constraint

s1

l1

Goal is to match a concrete state to the next program

location in our trace

Follow the trace!

Page 27: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Guidance Strategys0

s2

s3

s1

l1

l2

ln

Page 28: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Guidance Strategys0

s2

s3

s1

l1

l2

ln

Flip a fair coin and move forward

Page 29: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Guidance Strategys0

s2

s3

s1

s5 s6s4

l1

l2

ln

Distance heuristic to choose nearest to next location on the current trace

Page 30: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Our SolutionPossible errorslocations from

imprecise analysis tools

Generate backward

slicesto possible

error locations

Runtime Environment

Sound error

detection

Add inter-thread dependenceinformation (refine)

Heuristics

Guided Symbolic Execution

Page 31: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Followed trace to predicate…A.run lstart

lock(elem)

check(elem)

A.check lstart

if(elem.e > 9)

Exception

False in all successors

(zut!)

Page 32: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Where else is elem.e defined?Thread A {

void run (Element elem) { lock(elem)

check(elem)unlock(elem)

}

void check(Element elem) {if(elem.e > 9)

Throw exception

}}

Thread B {void run (Element elem) {

int x; // input variable

if( x > 18) {

lock(elem)

elem.reset();

unlock(elem)}

}}Object Element {

int e;Element() { e = 1;

}

void reset() {e = 11;

}}

Page 33: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Redefine a global variableB.run lstart

e := 11

A.run lstart

lock(elem)

check(elem)

unlock(elem) A.check lstart

if(elem.e > 9)

Exception

Page 34: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Generate a new backward sliceB.run lstart

e := 11

if(x > 18)

lock(elem)

unlock(elem) Element.reset lstart

elem.reset()

Thread B {void run (Element elem) {

int x; // input variable

if( x > 18) {

lock(elem)

elem.reset();

unlock(elem)}

}} Object Element {

int e;Element() { e = 1;

}

void reset() {e = 11;

}}

Page 35: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Updated Abstract SystemB.run lstart

e := 11

if(x > 18)

lock(elem)

unlock(elem) Element.reset lstart

elem.reset()

A.run lstart

lock(elem)

check(elem)

unlock(elem) A.check lstart

if(elem.e > 9)

Exception

Page 36: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Update Abstract TraceB.run lstart

e := 11

if(x > 18)

lock(elem)

Element.reset lstart

elem.reset()

A.run lstart

lock(elem)

check(elem)

A.check lstart

if(elem.e > 9)

Exception

Page 37: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Check Lock DependenciesB.run lstart

e := 11

if(x > 18)

lock(elem)

Element.reset lstart

elem.reset()

A.run lstart

lock(elem)

check(elem)

A.check lstart

if(elem.e > 9)

Exception

Page 38: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Update Abstract TraceB.run lstart

e := 11

if(x > 18)

lock(elem)

Element.reset lstart

elem.reset()

unlock(elem)

A.run lstart

lock(elem)

check(elem)

A.check lstart

if(elem.e > 9)

Exception

Thread B {void run (Element

elem) { int x; //

input variableif( x > 18)

{

lock(elem)

elem.reset();

unlock(elem)}

}}

Page 39: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Update Abstract StateB.run lstart

e := 11

if(x > 18)

lock(elem)

Element.reset lstart

elem.reset()unlock(elem)

A.run lstart

lock(elem)

check(elem)

A.check lstart

if(elem.e > 9)

Exception

Restart with this new trace from the initial

state

Page 40: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Slice and dice wants to find real errors and prove correct…

Don’t find an error yet have much to say

Goal is still to find errors

so optimize search

yet useful in no error

Page 41: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Abstract TraceA.run lstart

lock(elem)

check(elem)

unlock(elem) A.check lstart

if(elem.e > 9)

Exception

Thread A {void run (Element elem) {

lock(elem)

check(elem)unlock(elem)

}

void check(Element elem) {if(elem.e > 9)

Throw exception

}} Object Element {

int e;Element() { e = 1;

}

void reset() {e = 11;

}}

Page 42: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Slice and Dice Keep entire

abstraction Schedule only on

node in the abstraction

A.run lstart

lock(elem)

check(elem)

unlock(elem) A.check lstart

if(elem.e > 9)

Exception

Page 43: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

When it is time to refine…B.run lstart

e := 11

if(x > 18)

lock(elem)

Element.reset lstart

elem.reset()unlock(elem)

A.run lstart

lock(elem)

check(elem)

A.check lstart

if(elem.e > 9)

Exception…rather than

create a single trace…

Page 44: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Keep the entire abstractionB.run lstart

e := 11

if(x > 18)

lock(elem)

unlock(elem) Element.reset lstart

elem.reset()

A.run lstart

lock(elem)

check(elem)

unlock(elem) A.check lstart

if(elem.e > 9)

Exception

Page 45: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Visualization Demonstration

Page 46: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Belief

Sea of choices

Guided by belief

Guided-test and Slice-and-dice

Page 47: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

jpf-guided-test

50

Verification & Validation LabBrigham Young University

Provo, UT 84606, USA

http://vv.cs.byu.edu/

VV Lab, Brigham Young University, USA

Page 48: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

This slide left intentionally blank

Page 49: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Experimental Results A new GuidedSymbolic extension in Java

Pathfinder Uses the engine from the symbolic extension

(Pasareanu et. al. ISSTA 2008) Dynamic partial order reduction turned on Abstraction, refinement and heuristic

computation all performed on Java bytecode Libraries are part of the multi-threaded system

Page 50: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Multi-threaded Programs Reorder Benchmark

SLOC: 44, Reachability

Airline BenchmarkSLOC: 31, Reachability

VecDeadlock Real JDK 1.4 concurrent librarySLOC: 7267, Deadlock in Vector class

VecDeadlock Real JDK 1.4 concurrent librarySLOC: 7169, Deadlock in Vector class

VecRace Real JDK 1.4 concurrent librarySLOC: 7151, Race in ArrayList class

Page 51: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Error DiscoveryTi

me

in m

inut

es

60

30

20

10

Out of PatienceGuidedDFS

VecDeadlock0

VecDeadlock1

VecRace

Page 52: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

ComparisonTi

me

in se

cond

s

60

30

20

10

GuidedDFS

VecDeadlock0

VecDeadlock1

VecRace

Page 53: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Error Discovery

56

Subject Guided Search

Thread # States Time (secs) Memory

Reorder(9,1) 11 205 1.67 7MB

Reorder(10,1) 12 239 1.67 7MB

Airline(15,3) 16 1210 3.23 5MB

Airline(20,2) 21 3279 7.46 5MB

Airline(20,1) 21 3609 7.46 5MB

VecDeadlock0 2 1370 4.56 66MB

VecDeadlock1 2 2948 6.89 66MB

VecRace 2 3120 7.98 65MB

Page 54: Guided Test Visualization : Making Sense of Errors in  Concurrent  Programs

Error Discovery

57

Subject Abstraction-Refinement

Total tracelength

Refinements

Reorder(9,1) 13 1

Reorder(10,1) 13 1

Airline(15,3) 3 13

Airline(20,2) 3 19

Airline(20,1) 3 20

VecDeadlock0 14 1

VecDeadlock1 15 2

VecRace 12 1