Shape Analysis via 3-Valued Logic TVLA + Applications

Preview:

DESCRIPTION

Shape Analysis via 3-Valued Logic TVLA + Applications. Mooly Sagiv Tel Aviv University. Shape Analysis with Applications. http://www.cs.tau.ac.il/~rumster/TVLA /. Outline. Basic ideas behind TVLA TVLA for Singly Linked Lists Reachability Applications (next week). TVP. The TVLA System. - PowerPoint PPT Presentation

Citation preview

1

Shape Analysisvia 3-Valued Logic

TVLA + ApplicationsMooly Sagiv

Tel Aviv University

http://www.cs.tau.ac.il/~rumster/TVLA/

Shape Analysis with Applications

2

Outline

Basic ideas behind TVLA TVLA for Singly Linked Lists Reachability Applications (next week)

3

The TVLA System

Input:– SOS using Predicate Logic

– Control Flow Graph

– A set of 3-valued structures at the start node

– Implementation hints

Output– The set of 3-valued structures at every control flow

node (labeled directed graphs)

– Textual error messages

TVP

TVS

4

tvla create include\empty -d

/* create.c */

Elements create() {

Elements *f, *x;

int i, size;

for(i=0; i<size; i++) {

f = malloc(sizeof(Elements));

f->n = x;

x = f;

}

return x;

}

c2tvp create

/* list.h */typedef struct node { struct node *n; int data} *Elements;

tvla create include\empty

5

tvla reverse include\list

c2tvp reverse

typedef struct node { struct node *n; int data;} *Elements;

Elements * reverse(Elements *x) { Elements *y, *t; y = NULL; while (x != NULL) { t = y; y = x; x = x n; y n = t; }return y;}

6

/* reverse.tvp */

%s PVar {x, y, t}

#include "include\pred.tvp"

%%

#include "include\cond.tvp"

#include "include\stat.tvp"

%%

// y = NULL

n_1 Set_Null_L(y) n_2

// while (x != NULL) {

n_2 Is_Null_Var(x) exit

n_2 Is_Not_Null_Var(x) n_3

// t = y

n_3 Copy_Var_L(t, y) n_4

// y = x

n_4 Copy_Var_L(y, x) n_5

// x = x->n

n_5 Get_Next_L(x, x) n_6

// y->n = NULL

n_6 Set_Next_Null_L(y) n_7

// y->n = t

n_7 Set_Next_L(y, t) n_2

// }

7

/* create.tvp */

%s PVar {x, f}

#include "include\pred.tvp"

%%

#include "include\cond.tvp"

#include "include\stat.tvp"

%%

// for(i=0; i<size; i++) {

n_1 uninterpreted() n_2

// f = malloc(sizeof(Elements));

n_2 Malloc_L(f) n_3

// f->n = x;

n_3 Set_Next_Null_L(f) n_4

n_4 Set_Next_L(f,x) n_5

// x = f;

n_5 Copy_Var_L(x, f) n_1

n_2 uninterpreted() exit

// }

8

/* pred.tvp */

/*************** Core Predicates *************/

foreach (z in PVar) {

%p z(v_1) unique box

}

%p n(v_1, v_2) function

/**********************************************/

/*********** Instrumentation Predicates *************/

%i is[n](v) = E(v_1, v_2) ( v_1 != v_2 & n(v_1, v) & n(v_2, v))

9

/* cond.tvp */

%action uninterpreted() {

%t "uninterpreted"

}

%action Is_Not_Null_Var(x1) {

%t x1 + " != NULL"

%f { x1(v) }

%p E(v) x1(v)

}

%action Is_Null_Var(x1) {

%t x1 + " == NULL"

%f { x1(v) }

%p !(E(v) x1(v))

}

%action Is_Eq_Var(x1, x2) {

%t x1 + " == " + x2

%f { x1(v), x2(v) }

%p A(v) x1(v) <-> x2(v)

}

%action Is_Not_Eq_Var(x1, x2) {

%t x1 + " != " + x2

%f { x1(v), x2(v) }

%p !A(v) x1(v) <-> x2(v)

}

10

stat.tvp%action Set_Null_L(x1) {

%t x1 + " = NULL"

{

x1(v) = 0

}

}

%action Copy_Var_L(x1, x2) {

%t x1 + " = " + x2

%f { x2(v) }

{

x1(v) = x2(v)

}

}

%action Malloc_L(x1) {

%t x1 + " = (L) malloc(sizeof(struct node)) "

%new

{

x1(v) = isNew(v)

}

}

11

stat.tvp (2)%action Get_Next_L(x1, x2) {

%t x1 + " = " + x2 + "->" + n

%f { E(v_1) x2(v_1) & n(v_1, v) }

%message (!E(v) x2(v)) -> "an illegal dereference to\n" +

n + " component of " + x2 + "\n"

{

x1(v) = E(v_1) x2(v_1) & n(v_1, v)

}

}

12

stat.tvp (3)

%action Set_Next_Null_L(x1) {

%t x1 + "->" + n + " = null"

%f { x1(v) }

%message (!E(v) x1(v)) -> "an illegal dereference to\n" +

n + " component of " + x1 + "\n"

{

n(v_1, v_2) = n(v_1, v_2) & !x1(v_1)

is[n](v) = is[n](v) & (!(E(v_1) x1(v_1) & n(v_1, v)) |

E(v_1, v_2) v_1 != v_2 &

(n(v_1, v) & !x1(v_1)) & (n(v_2, v) & !x1(v_2)))

}

}

13

stat.tvp (4)

%action Set_Next_L(x1, x2) {

%t x1 + "->" + n + " = " + x2

%f { x1(v), x2(v) }

%message (E(v, v1) x1(v) & n(v, v1)) ->

"Internal Error! assume that " + x1 + "->" + n + "==NULL"

%message (!E(v) x1(v)) -> "an illegal dereference to\n" +

n + " component of " + x1 + "\n"

{

n(v_1, v_2) = n(v_1, v_2) | x1(v_1) & x2(v_2)

is[n](v) = is[n](v) | E(v_1) x2(v) & n(v_1, v)

}

}

14

Typical Garbage Collector

Program

Variables

a

b

c

d

e

f

Reachability-based

15

Program

Variables

a

b

c

d

e

f

Typical Garbage Collector Reachability-based

16

Typical Garbage Collector

Program

Variables

a

b

c

d

e

f

Reachability-based

17

Reachability

Concrete semantics which records reachability from stack (global) variables

Useful for:– Compile-time Garbage Collection

– Saving calls to Dynamic Garbage Collection» No memory leaks

– Speeding-up static analysis

Instrumentation predicater[n, x](v) = E(v1) x(v1) & n*(v1, v)

18

/* create.c */

Elements create() {

Elements *f, *x;

int i, size;

for(i=0; i<size; i++) {

f = malloc(sizeof(Elements));

f->n = x;

x = f;

}

return x;

}

c2tvp create

/* list.h */typedef struct node { struct node *n; int data} *Elements;

tvla rcreate include\empty

19

tvla rreverse include\rlist

c2tvp reverse

typedef struct node { struct node *n; int data;} *Elements;

Elements * reverse(Elements *x) { Elements *y, *t; y = NULL; while (x != NULL) { t = y; y = x; x = x n; y n = t; }return y;}

20

tvla rfumble include\rlist

c2tvp fumble

typedef struct node { struct node *n; int data;} *Elements;

Elements* reverse(Elements *x){

Elements *y,*t; y = NULL;while (x!= NULL) {

t = xn;

y = x;xn = y;

x = t;}

return y;

21

/* rpred.tvp */

/*************** Core Predicates *************/

foreach (z in PVar) {

%p z(v_1) unique box

}

%p n(v_1, v_2) function

/**********************************************/

/*********** Instrumentation Predicates *************/

%i is[n](v) = E(v_1, v_2) ( v_1 != v_2 & n(v_1, v) & n(v_2, v))

foreach (z in PVar) {

%i r[n,z](v) = E(v_1) (z(v_1) & n*(v_1, v))

}

%i c[n](v) = n+(v, v)

22

rstat.tvp%action Set_Null_L(x1) {

%t x1 + " = NULL“

%message … ->

{

x1(v) = 0

r[n, x](v) = 0

}

}

%action Copy_Var_L(x1, x2) {

%t x1 + " = " + x2

%f { x2(v) }

{

x1(v) = x2(v)

r[n, x](v) = 0

}

}

%action Malloc_L(x1) {

%t x1 + " = (L) malloc(sizeof(struct node)) "

%new

{

x1(v) = isNew(v)

r[n, x](v) = isNew(v)

}

}

23

(1) Focus on v1: x(v1) cdr(v1,v)

y u1 ux

u1 ux cdr

cdr

r[cdr]

y ux

u1 ux

cdr

y u1 ux

u1 ux cdr

cdr

yu1 u.1

x

u.0

cdr

cdr

cdr

cdr

24

Benefit of Reachability

Predict memory leaks Separate disjoint data structures More precise semantic reduction

– x = x->n

25

Optimizations in TVLA

Order of constrains– Eliminate cycles

Lazy evaluation Functional properties Exploit sparseness OBDD representation Java representation

26

TVLA Design Mistakes

The operational semantics is written in too low level language– No types

– No local updates to specific predicate values

– No constants and functions

– No means for modularity

– No local variables and sequencing

– Combines UI with functionality

TVP can be a high level language TVLA3VLA

27

TVLA Experience

Quite fast on small programs– But runs on medium programs too

Not a panacea More instrumentation may lead to faster (and

more precise) analysis

Recommended