23
Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

  • View
    222

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

Detecting Memory Errors usingCompile Time Techniques

Nurit Dor

Mooly Sagiv

Tel-Aviv University

Page 2: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

Memory errors

Hard to detect– point of failure is not point of error

– difficult to reproduce

– Depends on the system’s architecture

Many result from pointer misuse Other types: out of bound reference

Page 3: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

Usage of dead storagemain()

{ int *x,*z;

x = (int *)malloc(sizeof(int));

free(x);

z = (int *)malloc(sizeof(int));

if (x==z)

printf(“ unexpected equality”);

}

usage of deallocated storage

Page 4: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

Dereference of NULL pointerstypedef struct element {

int value;

struct element *next;

} Elements

bool search(int value, Elements *c) {Elements *elem;for ( elem = c; c != NULL;elem = elem->next;)

if (elem->val == value)

return TRUE;

return FALSE

NULL dereference

Page 5: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

Dereference of NULL pointerstypedef struct element {

int value;

struct element *next;

} Elements

bool search(int value, Elements *c) {Elements *elem;for ( elem = c; elem != NULL;elem = elem->next;)

if (elem->val == value)

return TRUE;

return FALSE

Page 6: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

Memory leakage

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

Page 7: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

Memory leakage

Elements* reverse(Elements *c){

Elements *h,*g;h = NULL;while (c!= NULL) {

g = c->next;

c->next = h;

h = c;c = g;}

return h;

Page 8: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

Cleanness Rules that a program must obey Does not depend on a program’s specification Precondition rules for each statement type Some cleanness rules are integrated into the

programming language:– Type checking

– Array bound accesses

– Java dereference

Other cleanness rules are programmer responsibility

Page 9: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

Run-Time vs. Static

Property Run-Time Conservative

Static

Manual runs

Depends on test cases

Assures against bugs

Interferes production

False alarms

Scales for large programs ? ?

Page 10: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

Shape graph

Example

Characteristics– finite representation– “sharing” of run-time locations by:

“pointed-to by” and “reachable from” variables

1 2 3 5 7 11 13c

elem

c

elem

NULL

NULL

Page 11: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

Shape analysis

Initialization - empty shape graph Iteratively apply every program statement and

condition Stop when no more shape graphs can be derived

Page 12: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

Cleanness checking via shape analysis

Compute a set of possible shape graphs before every program statement

Check cleanness condition of every statement against any possible shape graph

Cleanness conditions are generated in a syntax directed fashion

Report violations with the “witness” shape graph

Page 13: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

Abstract interpretation

state ’

Operational semantics

statement s

abstract representation

state

concretization

Abstractsemantics

statement s abstract representation’

abstraction

Page 14: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

Dereference of NULL pointerstypedef struct element {

int value;

struct element *next;

} Elements

bool search(int value, Elements *c) {Elements *elem;for ( elem = c; c != NULL;elem = elem->next;)

if (elem->val == value)

return TRUE;

return FALSE

NULL dereference

Page 15: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

c

elem NULL

c NULL

c NULL

elem

elem

elem= elem next

Page 16: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

elem= elem next

c NULL

c NULL

elem

elem

c NULL

c NULL

elem

elem

c NULL elem

X

Page 17: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

Implementation PAG (Program Analysis Generator)

– C front-end

– Supply transfer functions and abstract representation

Input– C program under restrictions

» no recursion» no pointer arithmetic or casting

Output– graphical presentation of shape graphs

– list of potential cleanness violations

Page 18: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

Points-To analysis

Program analysis that computes information regarding the pointers in the program

Point-to pairs (p,a) p = &a; “ p points-to a”

Heap treatment (p,heapl):l: p= malloc(...) “ p points-to heapl - heap address

allocate at this statement”

Page 19: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

Empirical resultssec / leakage false alarms

Program Shape Analysis Points-to

search.c 0.02/0 0.01/5

null_deref.c 0.03/0 0.02/5

delete.c 0.05/0 0.01/7

del_all.c 0.02/0 0.01/6

insert.c 0.02/0 0.03/7

merge.c 2.08/0 0.01/8

reverse.c 0.03/0 0.01/7

fumble.c 0.04/0 0.02/6

rotate.c 0.01/0 0.01/5

swap.c 0.01/0 0.01/5

Page 20: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

Empirical resultssec / reference+dereference false alarms

Program Shape Analysis Points-to

search.c 0.02/0 0.01/0

null_deref.c 0.03/0 0.02/0

delete.c 0.05/0 0.01/0

del_all.c 0.02/0 0.01/4

insert.c 0.02/0

merge.c 2.08/0 0.01/5

reverse.c 0.03/0 0.01/0

fumble.c 0.04/0 0.02/0

rotate.c 0.01/0 0.01/1

swap.c 0.01/0 0.01/0

0.03/1

Page 21: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

False alarms

Abstraction not precise enough – acyclic lists

– trees

Infeasible paths

Page 22: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

Advantage

Detection of non trivial bugs Easy to use:

– Minimal false alarms (No false alarms on many linked list programs)

– Minimal user interactions(No annotations)

– Graphical output of control-flow graph and shape graphs

Significantly faster than verification tools

Page 23: Detecting Memory Errors using Compile Time Techniques Nurit Dor Mooly Sagiv Tel-Aviv University

Challenges

Scaling for large programs– Annotations

– Cheaper preprocessing

– Better interprocedural analysis

– Other programming languages

– Ignore unlikely cases - losing conservative

Other data structures (trees, cyclic lists) Applications that can benefit from this