visualizing memory graphs by thomas zimmermann and andreas zeller presented by giannakaras giorgos...

20
Visualizing Memory Graphs by Thomas Zimmermann and Andreas Zeller Presented by Giannakaras Giorgos University of Konstanz Department of Computer and Information Science Prof. Dr Stefan Leue, Wei Wei Software Visualization SS 2006

Upload: haylie-millham

Post on 14-Dec-2015

214 views

Category:

Documents


0 download

TRANSCRIPT

Visualizing Memory Graphsby

Thomas Zimmermann and Andreas Zeller

Presented by

Giannakaras Giorgos

University of KonstanzDepartment of Computer and Information Science

Prof. Dr Stefan Leue, Wei WeiSoftware Visualization

SS 2006

2

Outline

• Motivation

• Structure of Memory Graphs

• Obtaining Memory Graphs

• Conclusion

3

Motivation

GNU debugger GDB• Values are shown as texts.

Problem• A user will never notice if 2 pointers point to the same

address – except by thoroughly checking and comparing pointer values.

4

Motivation

GNU DDD debugger• Models memory as a

graph.• Each value in memory

becomes a vertex and references between values become edges between these vertices (i.e. pointers).

Drawback• Each and every pointer of a

data structure must be dereferenced manually.

5

Motivation

Memory graphs• A memory graph captures the program state as a graph.• The graph is extracted automatically from a program.

Usefulness• Checking if there are pointers pointing to a specific address.• Checking the number of elements a data structure has.• Checking if an allocated memory block is reachable from within

a module.• Checking if the tree changed during the last function call.

6

Example Graph

7

Structure of Memory Graphs

Graph Notation G = (V, E, root)

• V : set of vertices• E : set of edges• root : dedicated vertex root

Vertices v = (val, tp, addr)

• val : value• tp : type• addr : memory address

Edges e = (v1, v2, op)

• v1, v2 : related vertices• op : operation which takes the expression of v1 to construct the expression

of v2.

8

Structure of Memory Graphs

Edge Operations• Construct the name of the descendants from their parent’s name.

• Operations on edges leading from root to base variables initially set the name.

• We denote functions by λx.B – a function that has a formal parameter x and a body B.

• In our graph visualizations the operation body is shown as edge label with the formal parameter replaced by “()“.

Root• References all base variables of the program.

• Each vertex in the graph is accessible from the root.

9

Structure of Memory Graphs

Example1. C declaration of a struct f :

struct foo { int val; } f = {47};

2. Results in 2 vertices and an edge : Vf = ({…}, struct foo, 0x5678) Vf.val = (47, int, 0x9abc) ef.val = (vf, vf.val, opf.val)

3. Corresponding Memory Graph

10

Obtaining Memory Graphs

11

Obtaining Memory Graphs

To obtain a memory graph G = (V, E, root) :

• Let unfold(parent, op, G) be a procedure that takes the name of a parent expression parent and an operation op and unfolds the element op(parent), adding new edges and vertices to the memory graph.

• Initialize V = {root} and E = • Invoke unfold(root, λx.“name“) for each base variable name in the

program.• The expression expr = op(parent) that will be unfolded depends

on the structure of the expr :

12

Obtaining Memory Graphs• Aliases : if V already has a vertex v΄at the same address and

with the same type, do not unfold expr again. However insert an edge (parent, v΄, op) to the existing vertex.

• Records : if expr is a record containing n members m1, m2,...mn, add a vertex v = ({...}, tp, addr) to V, and an edge (parent, v, op) to E. For each mi {m1, m2, mn} invoke unfold(expr, λx.“x.mi“, G), unfolding the record members.

• Arrays : if expr is an array containing n members m[0] , m[1], ..., m[n-1], add a vertex v = ([...], tp, addr) to V and an edge (parent, v, op) to E. For each i {0, 1,..., n} invoke unfold(expr, λx.“x[i]“, G), unfolding the array elements.

• Pointers : if expr is a pointer with address value val, add a vertex v = (val, tp, addr) to V and an edge (parent, v, op) to E. Invoke unfold(expr, λx.“*(x)“, G), unfolding the element that expr points to.

• Atomic values : if expr contains an atomic value val, add a vertex v = (val, tp, addr) to V and an edge (parent, v, op) to E.

13

Obtaining Memory Graphs

Example

1. #include <stdio.h>2. #include <stdlib.h>

3. #define M 34. #define N 2

5. // _break is used to set the breakpoint6. void _break() {}

7. main() { 8. int dim2[M][N];9. int i, j;10. 11. for (i=0; i<M; i++)12. for (j=0; j<N; j++)13. dim2[i][j]=i*N+j;

14. _break(); }

<Root>

dim2

(int(*)[3][2])0xbffff2f0:

(int(*)0xbffff2ec:

3

i

(int(*)0xbffff2e8:

2

j

(int(*)[2])0xbffff2f0:

(int(*)[2])0xbffff2f8:

(int(*)[2])0xbffff300:

(int(*)0xbffff2f0:

0

(int(*)0xbffff2f4:

1

(int(*)0xbffff2f8:

2

(int(*)0xbffff2fc:

3

(int(*)0xbffff300:

4

(int(*)0xbffff304:

5

()[0]

()[0]

()[0]()[0]

()[1]()[1]

()[1]

()[1]()[2]

14

Graph DifferencesComparing program states• In an alternate program run,

all pointers can have different values, but still the same semantics.

• Comparing program states using a graph is a simple operation, since we try to detect the greatest common sub graph.

Usefulness• Comparing memory graphs

gives us the ability to detect exactly where a failure has occurred.

15

Graph Differences

Maximum common subgraph1. Create the set of all pairs of

vertices (v1, v2) with the same value and the same type, one from each graph.

2. Form the correspondence graph C whose nodes are the pairs from (1) .

3. The maximal common sub graph then corresponds to the complete sub graph of C that is not contained to any other complete sub graph.

Any vertex that is not on the clique indicates a difference between G1 and G2.

14 18 22

14 1815 22

next

nextnextnext

next

list

list

G1

G2

16

Drawing Memory Graphs

DOT graph layouter

• Layouts are nice and descriptive.

• They do not scale to large memory graphs (1000 vertices and more).

17

Drawing Memory Graphs

h3viewer

• Interactive graph rendering tool that allows the user to navigate along the graph.

• Clicking on any vertex brings it on the front, showing detailed information.

• By dragging and rotating the view, the user can quickly follow and examine data structures.

18

Conclusion – Future Work

Applications• Visualization of all data structures in memory and

capturing the entire program state.• Detection of common sub graphs to isolate

differences between program states – especially differences that cause failure.

Limitations – Drawbacks • Limitation in visualization : lack of capability to depict

graphs which contain more than 40.000 vertices.• Not easily task to detect cycles in very large graphs

which might cause endless recursions and eventually eating up all available heap space.

19

Conclusion – Future Work

Enhancements - Improvements • Summarizing parts of the graph – Instead of

showing all n elements of a list it might suffice to present only the basic shape of the list.

• Reducing the graph size : pruning the graph at a certain depth in order to restrict the view to a particular module or variable.

• Development of graph algorithms for the detection of specific trouble spots or invariant violations.

END OF PRESENTATION