910 likes | 917 Views
This article discusses shape analysis, a static analysis technique, using 3-valued logic evaluation. It introduces the abstract domain for analysis, the TVLA system, and presents the main results and applications of shape analysis.
E N D
Shape Analysisvia 3-Valued Logic Mooly Sagiv Tel Aviv University Shape analysis with applications Chapter 4.6 http://www.cs.tau.ac.il/~rumster/TVLA/
Main Results • A new abstract domain for static analysis • Abstract dynamically allocated memory • Abstract interpretation by Klenee’s 3-valued logic evaluation • A system TVLA • Input: • Structural operational semantics • Input Program • Output: the result of the analysis
Motivation • Dynamically allocated storage and pointers are an essential programming tools • Object oriented • Modularity • Data structure • But • Error prone • Inefficient • Static analysis can be very useful here
A Pathological C Program a = malloc(…) ; b = a; free (a); c = malloc (…); if (b == c) printf(“unexpected equality”);
Dereference of NULL pointers bool search(int value, Elements *c) {Elements *elem;for (elem = c; c != NULL; elem = elem->next;) if (elem->val == value) return TRUE; return FALSE typedef struct element { int value; struct element *next; } Elements
Dereference of NULL pointers bool search(int value, Elements *c) {Elements *elem;for (elem = c; c != NULL; elem = elem->next;) if (elem->val == value) return TRUE; return FALSE typedef struct element { int value; struct element *next; } Elements potential null de-reference
Memory leakage typedef struct element { int value; struct element *next; } Elements Elements* reverse(Elements *c){ Elements *h,*g;h = NULL;while (c!= NULL) { g = c->next; h = c; c->next = h; c = g; }return h;
Memory leakage typedef struct element { int value; struct element *next; } Elements Elements* reverse(Elements *c){ Elements *h,*g;h = NULL;while (c!= NULL) { g = c->next;h = c; c->next = h; c = g; }return h; leakage of address pointed-by h
t y NULL 1 2 3 NULL x Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; }
t y NULL 1 2 3 NULL x Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; }
t y 1 2 3 NULL x Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; NULL List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; }
Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y NULL 1 2 3 NULL List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x
Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y NULL 1 2 3 NULL List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x
Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y NULL 1 2 3 NULL List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x
Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y NULL 1 2 3 NULL List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x
Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y NULL 1 2 3 NULL List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x
Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y NULL 1 2 3 NULL List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x
Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y NULL 1 2 3 NULL List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x
Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y NULL 1 2 3 NULL List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x
Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y NULL 1 2 3 NULL List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x
Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y NULL 1 2 3 NULL List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x
Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y NULL 1 2 3 NULL List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x
t y x Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; }
t y NULL x Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; }
NULL Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x
Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y NULL List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x
Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y NULL List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x Materialization
Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y NULL List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x
Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y NULL List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x
Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y NULL List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x
Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y NULL List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x
Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y NULL List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x
Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y NULL List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x
Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x
Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y NULL List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x
Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; t y NULL List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; } x
Original Problem: Shape Analysis • Characterize dynamically allocated data • x points to an acyclic list, cyclic list, tree, dag, etc. • data-structure invariants • Identify may-alias relationships • Establish “disjointedness” properties • x and y point to structures that do not share cells
Why is Shape Analysis Difficult? • Destructive updating through pointers • pnext = q • Produces complicated aliasing relationships • Dynamic storage allocation • No bound on the size of run-time data structures • No syntactic names for locations • Data-structure invariants typically only hold at the beginning and end of operations • Need to verify that data-structure invariants are re-established
Formal: Summary node x Formalizing “. . .” Informal: x
Applications: Software Tools • Static detection of memory errors (cleanness) • dereferencing NULL pointers • dereferencing dangling pointers • memory leaks • What is in the heap? • list? doubly-linked list? tree? DAG? • disjoint? intertwined? • Static detection of logical errors • Is a shape invariant restored?
Properties of reverse(x) • On entry: x points to an acyclic list • On exit: y points to an acyclic list • On exit: x == NULL • On each iteration, x and y point to disjoint acyclic lists • All the pointer dereferences are safe • No memory leaks
Plan • Motivation • SWhile • An SOS for SWhile • An SOS for SWhile using predicate calculus • Simple Abstract interpretation using 3-valued logics • More precise abstract interpretation+ TVLA (next meeting)
The SWhile Programming Language Abstract Syntax sel:= car | cdr a := x | x.sel | null | n | a1 opa a2 b := true | false | not b | b1 opb b2 | a1 opr a2 S := [x := a]l | [x.sel := a]l | [x := malloc()]l | [skip] l | S1 ; S2| if [b]lthen S1else S2 | while [b]l do S
Dereference of NULL pointers [elem := c;]1 [found := false;]2 while ([c != null]3 && [!found]4) ( if ([elem->car= value]5) then [found := true]6 else [elem = elem->cdr]7 )
Structural Operational Semantics • The program state consists of: • current allocated objects • a mapping from variables into atoms, objects, and null • a car mapping from objects into atoms, objects, and null • a cdr mapping from objects into atoms, objects, and null • malloc() allocates more objects • assignments update the state
l1 l2 l3 {l1, l2, l3}, [x l1 ,y null], [l1 1, l2 2, l3 3], [l1l2, l2l3, l3 null] 1 2 3 x null y null Structural Operational Semantics • The program state S=<O, env, car, cdr>: • current allocated objects O • atoms (integers, Booleans) A • env: Var* A O {null} • car: A A O {null} • cdr: A A O {null}
cdr(env(x)) env(x) O undefined otherwise car(env(x)) env(x) O undefined otherwise • Ax.cdr(<O, env, car, cdr>) = • Ax.car(<O, env, car, cdr>) = The meaning of expressions • Aa: SA O {null} • Aat(s) = at • Ax(<O, env, car, cdr>) = env(x)
Structural Semantics for SWhileaxioms [assvsos] <x := a, s=(O, e, car, cdr)> (O, e[x Aas], car, cdr) [asscarsos] <x.car := a, (O, e, car, cdr)> (O, e, car[e(x) Aas], cdr) where env(x)O [asscdrsos] <x.cdr := a, (O, e, car, cdr)> (O, e, car, cdr[e(x) Aas]) where env(x)O [assmsos] <x := malloc(), (O, e, car, cdr)> (O {n}, e[x n], car, cdr) where nO [skipsos] <skip, s> s
[ifttsos] <if b then S1 else S2, s> <S1, s> [ifffsos] <if b then S1 else S2, s> <S2, s> if Bbs=tt if Bbs=ff [comp1sos] <S1 , s> <S’1, s’> <S1; S2, s> < S’1; S2, s’> [comp2sos] <S1 , s> s’ <S1; S2, s> < S2, s’> Structural Semantics for SWhile(rules)
Summary • The SOS is natural • Can handle: • errors, e.g., null dereferences • free • garbage collection • But does not lead to an analysis • The set of potential objects is unbounded • Solution: Three-Valued Kleene Predicate Logic