Runtime Debugging Using ReverseEngineered UML - PowerPoint PPT Presentation

1 / 21
About This Presentation
Title:

Runtime Debugging Using ReverseEngineered UML

Description:

records the method execution calls between objects. Logs each method call, the calling object's id, and the calling object's class type ... – PowerPoint PPT presentation

Number of Views:36
Avg rating:3.0/5.0
Slides: 22
Provided by: Marke9
Category:

less

Transcript and Presenter's Notes

Title: Runtime Debugging Using ReverseEngineered UML


1
Runtime Debugging Using Reverse-Engineered UML
  • Orest Pilskalns, Scott Wallace, Filaret Ilas
  • Washington State University

2
Runtime Debugging Using Reverse-Engineered UML
  • Motivation
  • Faults and Runtime Failures
  • Background
  • Simple Example
  • The Approach
  • Results

3
Motivation - Definitions
  • Fault missing or incorrect code.
  • Failure inability of a system to perform a
    function due to a fault
  • Runtime failure revealed by running the code.
  • Tests reveal runtime failure but often NOT the
    location of the fault responsible

4
Motivation Traditional Debugging Approach
  • Use and IDE and Debugger
  • 1. Place a watch on suspicious variables.
  • 2. Set break points.
  • 3. Execute the suspicious code segment and
    observe variables.
  • 4. Step through code as needed.

5
Motivation Notion of Distance
  • Syntactic Distance lines of executed code
    between fault and failure
  • Small - traditional approach works
  • Large - branching leads to exponential growth
  • Heuristic Distance distance based on intuitive
    beliefs
  • Intuitions viewed as creating a priority-queue of
    source-code locations developer will examine.
  • Location of the true fault in this priority-queue
    heuristic distance.

6
Goal
  • Provide an approach that helps find runtime
    faults by using reverse-engineered UML Sequence
    Diagrams.

7
Background (1)
  • Telles et al. 17 debugging is the process of
    understanding the behavior of a system to
    facilitate the removal of bugs
  • Case study Vans et al. 18 have shown that up
    to 46 of the debugging task was spent trying to
    understand the software at the design level.
  • Assumption Sequence Diagrams useful for
    understanding system behavior

8
Background (2)
  • Eagan et al 6, Jones at al 9 use color to
    differentiate between successful and failed code,
    and use brightness to indicate the percentage of
    tests that successfully or unsuccessfully
    traversed the code

9
Cache Consistency Example (1)
  • Two Main Objects
  • DataSource provides volatile dataset Methods
  • getVersion(), setVersion(Version v)
  • getData(), setData(Dataset ds)
  • getType(), setType(int t)
  • DataConsumer reads DataSource and caches by
    using version to check for staleness
  • CacheltDataSource,DataSet,Versiongt cache
  • invert() // switches DataSet types using
    setType()
  • getPoint(int s, int n) // gets data point n from
    Dataset s

10
Cache Consistency Example (2)
  • Each time a dataset is obtained from a
    DataSource, the version is stored in the cache.
  • Data point retrieval getPoint() first looks for
    a cache entry with a current version match
  • Otherwise, DataSource.getData() is invoked to get
    a new copy of the dataset

11
Cache Consistency Example (3)
  • Example relies on DataSource.getVersion() to
    indicate when the DataSource has changed
  • Consider

12
Approach
  • 1. Create Unit Tests
  • 2. Instrument source code
  • 3. Execute tests Partition paths
  • 5. Aggregate paths
  • 6. Generate Sequence Diagram
  • 7. Reason about fault

13
Unit Tests
  • Relies upon unit tests that provide coverage of
    the code that produces the fault.
  • Additional unit tests are needed to provide
    coverage of the code using test cases that do not
    fail.
  • Test coverage is important since our objective is
    to differentiate between successful code and
    faulty code.

14
Unit Tests
  • public void testSuccess()
  • consumer.invert()
  • for( int i 1 i lt nTests i )
  • consumer.setInitialValues( i )
  • assertEquals( new Point2D.Double( 0.0, i ),
  • consumer.getPoint( 1, 0 ) )
  • assertEquals( new Point2D.Double( 3, i6 ),
  • public void testFail()
  • consumer.setInitialValues( 1 )
  • assertEquals( new Point2D.Double( 3, 7),
  • consumer.getPoint( 0, 3 ) )
  • assertEquals( new Point2D.Double( 3, -8),
  • consumer.getPoint( 1, 3 ) )
  • consumer.invert()
  • // fails! cache is out of sync!
  • assertEquals( new Point2D.Double( 3, 7 ),

15
Instrumenting the Code
  • process of inserting tracing code (in Java Byte
    Code)
  • records the method execution calls between
    objects.
  • Logs each method call, the calling objects id,
    and the calling objects class type
  • Since our goal is to create Sequence Diagrams, we
    chose to track method calls.

16
Execute and Partition Paths
  • The instrumented byte code is traversed using the
    unit tests.
  • Each unit test generates an object-method trace
    through the code, which is recorded to an XML
    trace file.
  • Partitioning occurs by tagging each test as
    successful or unsuccessful

17
Aggregate Trace Paths
  • Trace ti,G DAG, but ti has a branching factor
    of one.
  • 1. Initially, set mg to the root of G and mt to
    the root of ti.
  • 2. Place a pointer pg at mg and another pointer
    pt at mt.
  • 3. For each child of the node pointed to by pg,
    scan forward in ti for a matching object method
    call.
  • 4. If a matching pair is not found, repeat the
    scan forward in ti from mt trying all
  • descendents of pg in a breadth-first fashion. If
    no match is found, add the directed
  • graph rooted at mt as a new child of the node
    pointed to by mg. The algorithm is
  • now complete no new merging has occured.
  • 5. Otherwise, the nodes at pg and pt are the same
    object-method call and represent a
  • rejoining of the graph G and the trace ti.
    Splice a new branch between mg and tg
  • that includes the sequence between mt and pt
    exclusive of these endpoints. Repeat
  • from step 2.

18
After Merging
19
Transform Into Sequence Diagram
  • 1. When a vertex contains more then one child and
    at least one child represents a failed test,
    create a new Sequence Diagram (if not already
    created) and create a combined fragment for each
    child vertex. Each child vertex should be
    represented as an object in the Sequence Diagram.
  • 2. For each newly added child vertex, check its
    children, if is contains only one child, add the
    child vertex to the combined fragment and connect
    to the parent vertex using the method call in the
    previous vertex (label appropriately). If it
    contains more than one child return to step one.

20
SEQUENCE DIAGRAM
21
Conclusions
  • find bugs where sequence of events collaborate to
    create a failed test, instead of looking for
    broken statements.
  • provide design level information for better
    comprehension
Write a Comment
User Comments (0)
About PowerShow.com