260 likes | 378 Views
Safe Programming with Pointers through Stateful Views. Dengping Zhu Hongwei Xi Boston University. Outline. Introduction Programming with Stateful Views Related Work and Conclusion. Introduction. Direct memory manipulation Useful. E.g., Pointers in C. p + n : pointer arithmetic
E N D
Safe Programming with Pointersthrough Stateful Views Dengping Zhu Hongwei Xi Boston University
Outline • Introduction • Programming with Stateful Views • Related Work and Conclusion Safe Programming with Pointers through Stateful Views
Introduction • Direct memory manipulation • Useful. E.g., Pointers in C. p + n : pointer arithmetic • Dangerous. No safety guarantee. • Dangling pointers • Segmentation faults, Bus errors, … • X = * (p+n) // potentially out-of-bounds • Difficult to debug! Safe Programming with Pointers through Stateful Views
Motivation • Use types to enforce more safety properties • Make programming with pointers safe e.g: x = * p : we want p not to be a dangling pointer x = * (p + n) : we want n to be within the array bounds • How to achieve this? Safe Programming with Pointers through Stateful Views
Dependent Types • Can capture more program properties e.g: 5: int(5); 3: int(3); • Add: (Int, Int) -> Int With dependent types: Add: m: int. n: int. (int(m), int(n)) -> int(m+n) Safe Programming with Pointers through Stateful Views
Dependent Types • list (T, I) : the type for lists of length I in which each element is of type T. • List reversal: • a: type. n: int. list (a, n) -> list (a, n) Safe Programming with Pointers through Stateful Views
Guarded Types • Type guards: P e.g.: n > 0 • Guarded types: P T e.g. : factorial : a:int. a 0 (int(a) Int) where Int a: int. int(a) is the type for all integers. Safe Programming with Pointers through Stateful Views
Asserting types • The form: P T • Example: a function from non-negative integers to negative integers a : int. a 0 (int(a) -> a’ : int. ( a’ < 0) int(a’)) Safe Programming with Pointers through Stateful Views
Stateful Views • To model memory data layouts • Primitive views: T@L • T is a type • L is a memory address • A value of type T is stored at address L • E.g.: int(5) @ 100 : 5 is stored at address 100 100 5 Safe Programming with Pointers through Stateful Views
Stateful Views • Other stateful views are built on top of primitive views • Adjacent views: (T1@L, T2@L+1) • A value of type T1 is stored at L • A value of type T2 is stored at L+1 • May be written as (T1, T2) @ L L L+1 T1 T2 Safe Programming with Pointers through Stateful Views
Stateful Views • Example: getVar: a:type. l:addr. (a@l ptr(l)) (a@l a) • Read from a pointer • Prevent from reading dangling pointers! • Address polymorphism setVar: a:type. l:addr. (top@l a, ptr(l)) (a@l1) • Question: how to treat recursive data structures? Safe Programming with Pointers through Stateful Views
Recursive Stateful Views • For instance: array arrayView (T, I, L) : an array of type T with length I is stored at address L L L No Memory No Memory arrayView(T,0,L) L+1 L L … … T@L arrayView(T,I,L+1) arrayView(T,I+1,L) Safe Programming with Pointers through Stateful Views
View Change • A data structure can have different views. • How to switch? – View change functions e.g.: split arrayView(a,n,L) L L+i arrayView(a,i,L) arrayView(a,n-i,L+i) a:type. n:int. i:nat. l:addr. i n (arrayview (a, n, l) –o (arrayview (a, i, l), arrayView (a, n-i, l+i)) Safe Programming with Pointers through Stateful Views
Outline • Introduction • Programming with Stateful Views • Related Work and Conclusion Safe Programming with Pointers through Stateful Views
Swap swap: t1:type. t2:type. l1:addr. l2:addr. (t1@l1, t2@l2 ptr(l1), ptr(l2)) -> (t2@l1, t1@l2 unit) fun swap {t1:type, t2:type, l1:addr, l2:addr} (pf1: t1@l1, pf2: t2@l2 p1: ptr(l1), p2: ptr(l2)) : (t2 @ l1, t1 @ l2 unit) = let val (pf1’ tmp1) = getVar (pf1 p1) val (pf2’ tmp2) = getVar (pf2 p2) val (pf1’’ _ ) = setVar (pf1’ tmp2, p1) val (pf2’’ _) = setVar (pf2’ tmp1, p2) in (pf1’’, pf2’’ ‘()) end l1 l2 t1 t2 t1 t2 pf1’’ pf1 pf2’ pf2’’ pf2 pf1’ Safe Programming with Pointers through Stateful Views
Swap • Certain proofs can be consumed and generated implicitly • For instance: fun swap {t1:type, t2:type, l1:addr, l2:addr} (pf1: t1@l1, pf2: t2@l2 p1: ptr(l1), p2: ptr(l2)) : (t2 @ l1, t1 @ l2 unit) = let val tmp := !p1 in p1 := !p2; p2 := tmp end Safe Programming with Pointers through Stateful Views
Array • dataview arrayView (type, int, addr) = | {a:type, l:addr} ArrayNone (a, 0, l) | {a:type, n:nat, l:addr} ArraySome (a, n+1, l) of (a@l, arrayView (a, n, l+1)) ArrayNone : a: type. l:addr. () –o arrayView (a, 0, l) ArraySome: a: type. l:addr. n: nat. (a@l, arrayView(a, n, l+1)) –o arrayView (a, n+1, l) Safe Programming with Pointers through Stateful Views
Array • getFirst (get out the first element of a nonempty array): a: type. n: int. l: addr. n > 0 (arrayView (a, n, l) | ptr(l)) -> (arrayView (a, n, l) | a) fun getFirst {a:type, n:int, l:addr | n > 0} (pf : arrayView (a, n, l) | p : ptr(l)) : (arrayView (a, n, l) | a) = let prval ArraySome (pf1, pf2) = pf val (pf1’ | x) = getVar (pf1 | p) in (ArraySome (pf1’, pf2) | x) end arrayView(a,n,l) l l l+1 … … a@l arrayView(a,n-1,l+1) pf1’ pf1 pf2 Safe Programming with Pointers through Stateful Views
Array • Safe subscripting function: a:type.n: int. i: nat. l: addr. n > i ((arrayView (a, n, l) | ptr(l), int(i)) (arrayView (a, n, l) | a) • How to implement? Pseudo-code for a naïve implementation: fun sub (p, offset) = if offset = 0 then getFirst p else sub (p+1, offset – 1) • Safe! But, O(i)-time !!! Safe Programming with Pointers through Stateful Views
Array • An implementation in C int sub (int [ ] p, int offset) = * (p + offset) • O(1)-time. But, unsafe. • We want: O(1)-time + safe • How to do it? Safe Programming with Pointers through Stateful Views
Array • View Change • For any 0 i n, an array of size n at address L can be viewed astwo arrays: • One of size i at L • The other of size n – i at L+i • The split function • The unsplit function arrayView(a,n,L) L L+i arrayView(a,i,L) arrayView(a,n-i,L+i) Safe Programming with Pointers through Stateful Views
Array • Our implementation fun sub {a: type, n: int, i: nat, l: addr | n > i} (pf: arrayView (a, n, l) | p: ptr(l), i: int(i)) : (arrayView (a, n, l) | a) = let // the following line is erased before execution prval (pf1, pf2) = split (pf) val (pf2’ | x) = getFirst (pf2 | p + i) in // ‘unsplit’ is erased // before execution (unsplit (pf1, pf2’) | x) end pf arrayView(a,n,l) l L+i arrayView(a,i,l) arrayView(a,n-i,l+i) pf1 pf2 pf2’ Safe Programming with Pointers through Stateful Views
More Examples • Find more on-line • Singly-linked lists : cyclic buffer, … • Doubly-linked lists • Doubly-linked binary trees: splay trees, … • …… • Implementation is done in ATS http://www.cs.bu.edu/~hwxi/ATS/ Safe Programming with Pointers through Stateful Views
Outline • Introduction • Programming with Stateful Views • Related Work and Conclusion Safe Programming with Pointers through Stateful Views
Conclusion • The notion of stateful views provides a general and flexible approach to safe programming with pointers • The need for view changes during programming • The use of dataviews in describing memory layouts • Separation between memory allocation and initialization • …… Safe Programming with Pointers through Stateful Views
Some Related Work • Separation logic. Reynolds, 2002. • Shape analysis. Sagiv, Reps and Wihelm, 1998. • Alias types. Walker and Morrisett, 2000. • A type theory for memory allocation and data layout. Petersen, L., R. Harper, K. Crary and F. Pfenning, 2003. • Type refinements. Mandelbaum, Y., D. Walker and R. Harper, 2003. • Xanadu. H. Xi, 2000. • …… Safe Programming with Pointers through Stateful Views