Verification of Pointer Programs

With this dissertation we present an abstraction and verification framework for pointer programs operating on unbounded heaps. To this end, we introduce two different abstraction methods for pointer-manipulating programs: an abstraction technique for singlylinked structures that guarantees a finite abstract semantics for any given program and a more general approach, employing context-free hyperedge replacement graph grammars to model the data structures and compute the abstraction mappings. The graph grammars are user defined and therefore this approach can handle a variety of different data structures. By means of partial concretization steps we avoid the necessity for explicitly defining the effect of pointer-manipulating operations on abstracted parts of the heap: it is obtained “for free” by combining partial concretization, the concrete pointer operation, and re-abstraction of the transformed state. Besides the possibility to check for pointer safety, assuring the absence of null dereferences, and shape safety, the preservation of the data structure, we establish an expressive pointer logic that is based on LTL. It allows to specify safety as well as liveness properties for the executions of the system. We show that the corresponding model checking problem can be reduced to an LTL model checking problem enabling the application of existing, highly optimized model checkers. We show the practical feasibility of our approach by applying it to the well-known Deutsch-Schorr-Waite traversal algorithm for binary trees – a stackless traversal algorithm that uses destructive updates. Finally, we introduce an extension of our framework to concurrent pointer programs with unbounded thread creation. For that purpose we model the control-flow and heap semantics separately as Petri nets. Abstracting the heap only, we obtain a data-abstract semantics for which we can show that the model checking problem is decidable. To obtain practically feasible results, however, we are forced to apply in a second step abstraction to the control-flow semantics as well. It turns out that the resulting Petri net can be represented as a finite transition system, to that our model checking method can be applied. Zusammenfassung In dieser Dissertation stellen wir ein Konzept zur Abstraktion und Verifikation zeigermanipulierender Programme, welche über unbeschränkten Speicher verfügen, vor. Dafür führen wir zwei unterschiedliche Abstraktionstechniken ein: Die erste dient der Abstraktion von einfach verketteten Datenstrukturen und garantiert die Endlichkeit der abstrakten Semantik für alle Eingaben, während ein erweiterter Ansatz Hyperkantenersetzungsgrammatiken zur Modellierung komplexerer Datenstrukturen und zur Berechnung der zugehörigen Abstraktionsabbildungen einsetzt. Die verwendeten Graphgrammatiken werden vom Benutzer vorgegeben und sind daher nicht auf bestimmte Datenstrukturen beschränkt. Durch die Verwendung partieller Konkretisierungsschritte können wir es vermeiden, für jede Programmoperation eine abstrakte Version bereitstellen müssen. Dabei ergibt eine Kombination aus partieller Konkretisierung, Ausführung der konkreten Programmoperation und anschließender Reabstraktion den entsprechenden abstrakten Transformationsschritt. Die vorgestellten Verifikationsmethoden ermöglichen es uns nicht nur, mögliche Laufzeitfehler, wie sie etwa durch Dereferenzierung von Null-Zeigern entstehen, festzustellen, und die Invarianz von Datenstrukturen im Hinblick auf einen gegebenen Algorithmus zu testen. Die Einführung einer auf LTL basierenden, ausdrucksstarkenHeap-Logik erlaubt es uns, auch Sicherheitsund Lebendigkeitseigenschaften aller Läufe des Systems zu überprüfen. Wir zeigen, dass das zugehörige Model Checking-Problem auf LTL Model Checking zurückgeführt werden kann, und somit die Anwendung vorhandener, bewährter Model Checking-Verfahren möglich ist. Anhand des Deutsch-Schorr-Waite-Traversierungsalgorithmus, der ohne zusätzlichen Kellerspeicher oder andere Hilfsstrukturen auskommt, zeigen wir die praktische Anwendbarkeit unseres Konzepts, indem wir verschiedene Korrektheitseigenschaften nachweisen. Abschließend erweitern wir unseren Ansatz um dynamische und unbeschränkte Threaderzeugung zur Laufzeit. Dazu modellieren wir Kontrollflussund Heapsemantik unabhängig voneinander als Petri-Netze. Durch Abstraktion des Heaps erhalten wir eine datenabstrakte Semantik, für die die Entscheidbarkeit des Model Checking-Problems nachgewiesen werden kann. Für praktisch nutzbare Ergebnisse sind wir jedoch gezwungen, in einem zweiten Schritt auch die Kontrollflusssemantik zu abstrahieren. Das daraus resultierende Petri-Netz kann als endliches Transitionssystem dargestellt werden, auf welches wiederum unsere Verifikationsverfahren anwendbar sind.

[1]  Neil Immerman,et al.  Simulating Reachability Using First-Order Logic with Applications to Verification of Linked Data Structures , 2005, CADE.

[2]  John C. Reynolds,et al.  Separation logic: a logic for shared mutable data structures , 2002, Proceedings 17th Annual IEEE Symposium on Logic in Computer Science.

[3]  Annegret Habel,et al.  Hyperedge Replacement, Graph Grammars , 1997, Handbook of Graph Grammars.

[4]  Reinhard Wilhelm,et al.  Solving shape-analysis problems in languages with destructive updating , 1998, TOPL.

[5]  Hsu-Chun Yen,et al.  A Unified Approach for Deciding the Existence of Certain Petri Net Paths , 1992, Inf. Comput..

[6]  Thomas Noll,et al.  Juggrnaut: Graph Grammar Abstraction for Unbounded Heap Structures , 2010, TTSS.

[7]  J. A. Robinson,et al.  Handbook of Automated Reasoning (in 2 volumes) , 2001 .

[8]  Andreas Podelski,et al.  Boolean Heaps , 2005, SAS.

[9]  Martin C. Rinard,et al.  Pointer and escape analysis for multithreaded programs , 2001, PPoPP '01.

[10]  Shin Nakajima,et al.  The SPIN Model Checker : Primer and Reference Manual , 2004 .

[11]  Jan Friso Groote,et al.  An Efficient Algorithm for Branching Bisimulation and Stuttering Equivalence , 1990, ICALP.

[12]  Thomas Noll,et al.  Composing Transformations to Optimize Linear Code , 2007, ICTAC.

[13]  Kedar S. Namjoshi,et al.  Shape Analysis through Predicate Abstraction and Model Checking , 2003, VMCAI.

[14]  Arend Rensink,et al.  Model Checking Dynamic States in GROOVE , 2006, SPIN.

[15]  Joost-Pieter Katoen,et al.  Safety and Liveness in Concurrent Pointer Programs , 2005, FMCO.

[16]  Amir Pnueli,et al.  Shape Analysis by Predicate Abstraction , 2005, VMCAI.

[17]  Martin C. Rinard,et al.  Pointer analysis for multithreaded programs , 1999, PLDI '99.

[18]  Ahmed Bouajjani,et al.  Abstract Regular Tree Model Checking of Complex Dynamic Data Structures , 2006, SAS.

[19]  Paolo Baldan,et al.  Approximating the Behaviour of Graph Transformation Systems , 2002, ICGT.

[20]  Roman Manevich,et al.  Thread Quantification for Concurrent Shape Analysis , 2008, CAV.

[21]  Hong-Seok Kim,et al.  Bottom-Up and Top-Down Context-Sensitive Summary-Based Pointer Analysis , 2004, SAS.

[22]  Susan Horwitz,et al.  Pointer-Range Analysis , 2004, SAS.

[23]  Edmund M. Clarke,et al.  Design and Synthesis of Synchronization Skeletons Using Branching-Time Temporal Logic , 1981, Logic of Programs.

[24]  Hongseok Yang,et al.  Automatic Verification of Pointer Programs Using Grammar-Based Shape Analysis , 2005, ESOP.

[25]  Orna Grumberg,et al.  Abstract interpretation of reactive systems , 1997, TOPL.

[26]  Arend Rensink,et al.  Canonical Graph Shapes , 2004, ESOP.

[27]  Reinhard Wilhelm,et al.  Parametric shape analysis via 3-valued logic , 1999, POPL '99.

[28]  Joost-Pieter Katoen,et al.  Verifying Concurrent List-Manipulating Programs by LTL Model Checking , 2007 .

[29]  Patrice Godefroid,et al.  Partial-Order Methods for the Verification of Concurrent Systems , 1996, Lecture Notes in Computer Science.

[30]  David L. Dill,et al.  Experience with Predicate Abstraction , 1999, CAV.

[31]  Arend Rensink,et al.  Abstract Graph Transformation , 2006, SVV@ICFEM.

[32]  David L. Dill,et al.  Successive approximation of abstract transition relations , 2001, Proceedings 16th Annual IEEE Symposium on Logic in Computer Science.

[33]  Detlef Plump,et al.  Extending C for Checking Shape Safety , 2006, Electron. Notes Theor. Comput. Sci..

[34]  Christel Baier,et al.  Principles of model checking , 2008 .

[35]  Patrice Godefroid,et al.  Generalized Model Checking: Reasoning about Partial State Spaces , 2000, CONCUR.

[36]  Colin Runciman,et al.  Checking the Shape Safety of Pointer Manipulations , 2003, RelMiCS.

[37]  Radha Jagadeesan,et al.  Model checking partial state spaces with 3-valued temporal logics , 2001 .

[38]  Colin Runciman,et al.  Specifying Pointer Structures by Graph Reduction , 2003, AGTIVE.

[39]  Hans-Jörg Kreowski,et al.  Grammatical Inference Based on Hyperedge Replacement , 1990, Graph-Grammars and Their Application to Computer Science.

[40]  B. König,et al.  Verifying Finite-State Graph Grammars: An Unfolding-Based Approach , 2004, CONCUR.

[41]  D. Kozen Results on the Propositional µ-Calculus , 1982 .

[42]  Mogens Nielsen,et al.  Decidability Issues for Petri Nets - a survey , 1994, Bull. EATCS.

[43]  Joost Engelfriet,et al.  A Greibach Normal Form for Context-free Graph Grammars , 1992, ICALP.

[44]  Jean-Luc Lambert,et al.  A Structure to Decide Reachability in Petri Nets , 1992, Theor. Comput. Sci..

[45]  Amir Pnueli,et al.  The temporal logic of programs , 1977, 18th Annual Symposium on Foundations of Computer Science (sfcs 1977).

[46]  Thomas Noll,et al.  Verifying Dynamic Pointer-Manipulating Threads , 2008, FM.

[47]  Thomas A. Henzinger,et al.  Lazy Shape Analysis , 2006, CAV.

[48]  William M. Waite,et al.  An efficient machine-independent procedure for garbage collection in various list structures , 1967, CACM.

[49]  Eran Yahav,et al.  Verifying safety properties of concurrent Java programs using 3-valued logic , 2001, POPL '01.

[50]  Thomas Noll,et al.  Abstracting Complex Data Structures by Hyperedge Replacement , 2008, ICGT.

[51]  Patrick Cousot,et al.  Systematic design of program analysis frameworks , 1979, POPL.

[52]  Mark N. Wegman,et al.  Analysis of pointers and structures , 1990, SIGP.

[53]  Gary Lindstrom,et al.  Scanning List Structures Without Stacks or Tag Bits , 1973, Information Processing Letters.

[54]  Alexey Gotsman,et al.  Thread-modular shape analysis , 2007, PLDI '07.

[55]  Jeffrey D. Ullman,et al.  Introduction to Automata Theory, Languages and Computation , 1979 .

[56]  Jianwen Zhu,et al.  Symbolic pointer analysis revisited , 2004, PLDI '04.

[57]  Rob J. van Glabbeek,et al.  Branching time and abstraction in bisimulation semantics , 1996, JACM.

[58]  Thomas W. Reps,et al.  Automated Verification of the Deutsch-Schorr-Waite Tree-Traversal Algorithm , 2006, SAS.

[59]  Javier Esparza,et al.  On the Decidability of Model Checking for Several µ-calculi and Petri Nets , 1994, CAAP.

[60]  Yassine Lakhnech,et al.  On Logics of Aliasing , 2004, SAS.

[61]  Joost Engelfriet,et al.  Context-free graph languages of bounded degree are generated by apex graph grammars , 1994, Acta Informatica.

[62]  Orna Grumberg,et al.  Don't Know in the µ-Calculus , 2005, VMCAI.

[63]  Patrick Cousot,et al.  Abstract interpretation: a unified lattice model for static analysis of programs by construction or approximation of fixpoints , 1977, POPL.