Advanced Interprocedural Analysis Using 3-Valued Logic for Dynamic Object Management
This work explores interprocedural program analysis utilizing 3-valued logic, focusing on managing dynamically created objects in the heap and stack environments. We propose abstract domains reflecting unboundedness through fixed sets of program entities, including call strings and dynamic lists. The paper addresses significant challenges like pointer dereferencing, memory leaks, and the behavior of shared objects amid concurrency. Through examples like in-situ list reversal, we illustrate how to analyze complex structures, ensuring safe pointer operations and memory management.
Advanced Interprocedural Analysis Using 3-Valued Logic for Dynamic Object Management
E N D
Presentation Transcript
Program Analysisvia 3-Valued Logic Mooly Sagiv, Tal Lev-Ami, Roman Manevich Tel Aviv University Thomas Reps, University of Wisconsin, Madison Reinhard Wilhelm, Universität des Saarlandes
Interprocedural Analysis, so far Abstract domains • (Powerset of) fixed set of program entities andentities from underlying domain • Domains: • P(Aexp*) Available expressions • P(Var* Lab* ) Reaching Definitions • Var* Val Constant Propagation • Var* Int Interval Analysis
Interprocedural Analysis • Dynamically created procedure incarnations • Domain P(Lab* (Var* …)) • Call strings – strings of labels ofcall sites • Sufficient to represent recursion because of nested lifetimes, a call string corresponds to an actual stack • in general of unbounded length non-computable fixed point • approximated by fixed length, k
Dynamically Created “Objects” • How to represent dynamically created • heap cells, created by calls to mallocx=malloc();… x=malloc();… x=malloc(); • objects, created by constructors of classesx=new C;… x=new C;… x=new C; • threads, created by thread constructors • In general, • unbounded sets • non-nested lifetimes • anonymous
Anonymous Objects (contd.) • Concrete domains: relations reflecting accessibility, • Stack for program variables • Heap for anonymous, dynamically created objects • pointer variables point from Stack into Heap • Heap consists of a set of functions modelling references/pointer components • Abstract domains: How to deal with unboundedness? • How to analyze programs without bounds on number of objects?
Invariant: x points to head of non-reversed suffix, y to head of already reversed prefix or NULL (start) Example: In-Situ List Reversal typedef struct list_cell { int val; struct list_cell *next; } *List; Reverses lists of arbitrary length List reverse (List x) { List y, t; y = NULL; while (x != NULL) { t = y; y = x; x = x next; y next = t; } return y; }
Questions Posed to the Analysis • Can x be dereferenced while having value NULL in some execution state? • Can an object leak out of the program’s execution? • Can an object be freed while being shared?
Freeing a Shared Object a = malloc(…) ; b = a; free (a); c = malloc (…); if (b == c) printf(“unexpected equality”);
Dereferencing a NULL pointer 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
Dereferencing a NULL pointer 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* strange(Elements *x){ Elements *y,*g;y = NULL;while (x!= NULL) { g = x->next; y = x; x->next = y; x = g; }return y;
Memory Leakage typedef struct element { int value; struct element *next; } Elements Elements* strange (Elements *x){ Elements *y,*g;y = NULL;while (x!= NULL) { g = x->next;y = x; x->next = y; x = g; }return y; leakage of list elements
class Make { private Worklist worklist; public static void main (String[] args) { Make m = new Make(); m.initializeWorklist(args); m.processWorklist(); } void initializeWorklist(String[] args) { ...; worklist = new Worklist(); ... // add some items to worklist} void processWorklist() { Set s = worklist.unprocessedItems(); for (Iterator i = s.iterator(); i.hasNext()){ Object item = i.next(); if (...) processItem(item); } } void processItem(Object i){ ...; doSubproblem(...);} void doSubproblem(...) { ... worklist.addItem(newitem); ... } } public class Worklist { Set s; public Worklist() {. ..; s = new HashSet(); ... } public void addItem(Object item) { s.add(item); } public Set unprocessedItems() { return s; } } return rev; }
Example: In-Situ List Reversal Concrete execution on a list of length 3
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
Original Problem: Shape Analysis • Characterize dynamically allocated data structures • 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 data structures that do not share cells
Properties of reverse(x) • On entry: x points to an acyclic list • On exit: y points to an acyclic list • On exit: x = = NULL • Invariant: At the start of while loop, x points to head of non-reversed suffix, y to head of already reversed prefix or NULL (start)(they are disjoint acyclic lists) • All the pointer dereferences are safe • No memory leaks
Example: In-Situ List Reversal Abstract execution
t y x • could be • the empty list • a non-empty list 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
Materialization assuming that is not the empty list 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
Materialization assuming that is not the empty list 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
could be • the empty list • a non-empty list 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 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 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 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 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