From Reasoning Principles for Function Pointers To Logics for Self-Configuring Programs

Lead Research Organisation: University of Sussex
Department Name: Sch of Engineering and Informatics

Abstract

Pointers are an important feature of programming languages used to define dynamically growing and recursive data structures. Many languages provide pointers not just to data but also functions or procedures, i.e. to executable code. In high-level languages code pointers may manifest themselves explicitly in the form of function pointers or appear in disguises, e.g. as methods of objects carrying their own method suites. Thus, function pointers offer high flexibility of code organisation at runtime but their meaning in specification and verification has been poor due to their complexity. In order to build correct software for modern and future languages it is paramount to have logics that permit reasoning about programs including function pointers. It is important that reasoning is local and modular which means that verification can be done simply w.r.t. the part of the heap affected by a piece of code, and independently of other code that is going to be linked at a later stage, respectively.To develop such reasoning principles for code pointers and their disguised appearance as meta-programming features like run-time generation and loading of code is the objective of this project.In software production a huge amount of time goes into testing that programs are free from errors and thus do not show undesired or even harmful behaviour. While testing is only as good as the test data is, a much more rigorous approach is to verify that a program meets a certain specification, for example that it does not lead to memory faults. Programs containing pointers, however, are notoriously difficult to specify, let alone verify. As Sir Tony Hoare said back in 1973: The introduction of pointers into high-level languages has been a step backwards from which we may never recover.'' 30 years later pointers and references are still important language features and program verification is still the costly exception. But the recent development of Separation Logic (by Reynolds, O'Hearn and others) has finally presented us with a handle to tackle the complexity of pointers. It permits local reasoning on the heap, liberating the verifier from specifying and proving that most of the heap does not change when a procedure or command is executed. Alas, so far only pointers on first-order data like numbers or strings profit from this recent enhancement.Function pointers are equally useful however. They are often employed to implement event handling or automatic software configuration. Which handler is used (as callback'') depends on the content of the function pointer registered, i.e. assigned at runtime. Dynamic invocation of code, reminiscent of dynamic dispatch in object-oriented languages, can also be achieved via such pointers. Function pointers are therefore not simply a rare curiosity. In fact, they are commonplace and appear in languages like ML or C. The language C# even has a special type construct for them: delegates. In Java these can be simulated via single method interfaces. Interfaces, however, do not identify methods by type signatures alone which makes it hard to share them across libraries. Java developers address this by creating on-the-fly wrapper objects (proxies).This is a typical instance of a principle called Reflection that denotes the ability to introspect, intercede, and generate code in a programming language and thus constitutes a method of meta-programming. Another important reflection principle is dynamic loading which allows code modules (for instance software plugins for extended functionality) to be loaded at runtime. For such advanced features, some of which are not available in standard object-oriented languages yet, there are no adequate program logics. Therefore, the central objective of this project is to establish program (Hoare-) logics for languages with explicit and implicit code pointers making the benefits of Separation Logic amenable to them.

Publications

10 25 50
 
Description A proof system has been established in order to prove (memory safety) properties of imperative programs that can store procedures in memory. This has been proved sound and implemented in a tool. It has also been investigated how such a tool can support reasoning about reflective programs, i.e. programs that manipulate themselves at runtime.
To prove the correctness of this logic, a new 'hybrid' model has been devised.
Exploitation Route Other researchers in the verification community can use our results to support stored procedures in their languages and verifiers.
The 'hybrid' semantics (based on step indexing and domain theory) has been used in various papers (in notable conferences like POPL) to develop logics for concurrency. The corresponding paper (Birkedal et al) from the publication list has already a citation count of 62 on Google Scholar.. The paper 'Nested Hoare triples and frame rules for higher-order store' that introduced a semantics for nested triples has a citation count of 49 for the proceedings version and 33 for the journal version.
Sectors Digital/Communication/Information Technologies (including Software)

URL http://www.informatics.sussex.ac.uk/research/projects/PL4HOStore/
 
Description The hybrid semantics developed during the project in order to prove the soundness of the proposed proof system has been used by other researchers in the are to provide a semantic (and formal) foundation for their work, for instance logical relations. In the recent past the work by Birkedal and others on verification for concurrent systems made use of variations of the step-indexed semantics as produced in out POPL paper.
First Year Of Impact 2014
Sector Digital/Communication/Information Technologies (including Software)
 
Title Crowfoot verifier 
Description Crowfoot is a semi-automated verification tool we have developed for reasoning about programs which store procedures/code on the heap. Crowfoot uses symbolic execution based on separation logic to reason about programs, proving that procedures meet their specifications, which the user provides in the form of pre- and post-conditions. Crucially, the assertion language of Crowfoot includes the nested triples developed by Schwinghammer, Birkedal, Reus and Yang. This is what allows us to reason in a modular way about the behaviour of code stored on the heap. 
Type Of Technology Software 
Year Produced 2012 
Impact Used in teaching in MSc Advanced Comp Science at Sussex uni. 
URL http://www.informatics.sussex.ac.uk/research/projects/PL4HOStore/crowfoot/