Philipp Rimmele

SlimExc

Deterministic exception handling for C++ with GCC


SlimExc is an alternative Implementation of the C++ Exception Handling Mechanism for GCC which is developed by me and Valentin Felder. It aims to be a runtime- and memory-deterministic Implementation which is suitable for safety critical, time critical and embedded systems. It consists of a GCC Plugin and a C++-Library.

Full Documentation and Releases can be Downloaded here: https://data.philipp-rimmele.de/Downloads/SlimExc/Releases/
The Git-Repository for the SlimExc Library: https://data.philipp-rimmele.de/git/slimexc/library
The Git-Repository for the SlimExc GCC-Plugin: https://data.philipp-rimmele.de/git/slimexc/plugin

Status quo

The C++ standard exception handling implementation is not deterministic in the sense that no upper bound for the runtime and memory usage can be statically calculated1. Also the error path has a significantly increased runtime compared to the success path. Beyond that the initial size of the library which implements the necessary functionalities is not negligible on smaller systems. This makes it unsuitable for systems which are either time-, memory-, or safety-critical. For this reason the exception handling gets banned partially or completely in over 50% of all C++ projects1. Many projects resort to using other means of error handling, which can only ever represent a non-standard dialect of C++ and come with their own drawbacks1.

The goal of SlimExc

SlimExc aims to provide an alternative implementation of the C++ exception handling mechanisms, which is standard-conform to a high degree, while avoiding many of the issues of the standard implementation. Mainly, SlimExc

How it works

Return based approach

Every time an exception is thrown, the normal program execution must be interrupted and continued at the appropriate catch site. Therefore the stack must be unwound in some way until the the stackframe of the catch site is reached. In the C++ standard exception handling implementation this is done with a special stack-unwinding routine, which also takes care of the destructor calls for all objects on the stack. This routine is very runtime intensive. The SlimExc-Implementation instead uses return statements to unwind the stack. The return semantics also imply that all destructors for objects on the stack are called. A schematic overview of the different control flows is shown below.

Controlflow of default exception handling
Controlflow of Slim-Exception-handling

Exception storage on the stack

In the C++ standard exception handling implementation the exception object is either stored on the Heap (dynamic memory) or on the stack of the throw-site (stack-pinning). Both, stack-pinning and dynamic memory allocation, are not space- and/or time deterministic. The Slim-Exception-Implementation instead stores the exception object on the stack of the catch site. Therefore, no stack-pinning is needed. To realize this mechanism it is necessary to allocate the memory of the largest possible exception object already when a try-block is entered. This leads to a constant (deterministic) memory overhead for both the success and error paths.

Realization

In the SlimExc Implementation, the classic exception handling mechanisms with its keywords try, catch and throw get implicitly replaced with other inline code segments and calls to the SlimExc Library. This is realized recursively by the Slim-Exception-Plugin, which alters the Abstract syntax tree (AST) of the program at compile time.

About

The current implementation is a beta-version which we have developed in our spare time without additional ressources. To continue the development and maintenance of SlimExc, we are actively looking for partners and funding opportunities. SlimExc is an OpenSource Project under the GPLv3 (Plugin) and BSD (Library) License. Any Feedback and Bug-reports are appreciated. Please feel free to contact us here: "developer (at) philipp-rimmele . de".




1 https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0709r0.pdf