Dynamic Weaving with AspectC++


About the project

Current implementations of Aspect-Oriented Software Development usually target weaving at compile or load time. Providing infrastructure for weaving at runtime has proven to be a tough challenge, especially for static typed languages like C and C++

This Project provides infrastructure for weaving at runtime in AspectC++. This enables the programmer to use the very same aspect for both static and dynamic weaving. For that reason, we also call this project the single language approach.

This website presents our prototype implementation. Enjoy!

The static instrumentation aspect

In order to weave an aspect into a running program, the program needs to be instrumented at runtime, so that the dynamic aspect can be activated. This is done using an static aspect written in AspectC++. For the squid tracing example, we have used this aspect.

That means that in order to instrument your program, you need to implement an aspect that does nothing else than defining the pointcut where the instrumentation should happen. Ideally you would use something like the pointcut expression "% %::%(...)", which matches on every method in any class. In practice, we need to work around some parser bugs, so we exclude some join points manually.

The runtime system

The static instrumentation aspect "inherits" from an generic base aspect, which contains the actual implementation. Each Hook is represented by a JoinPointMonitor. That is a structure that effectively introduces a static member per potential dynamic join point into the binary. Static members are allocated into the bss segment by the linker and are therefore initialized to 0. When compiling the dynamic aspect to an DSO, these symbols are overloaded at load time, which technically weaves the dynamic aspect.

The introduced static member can be configured. It is either a SimpleAdviceContainer, that can only hold one dynamic advice per dynmic join point, or a ListAdviceContainer that uses a linked list to maintain the loaded advice implementations.

The dynamic loader

The actual loading at runtime is implemented in the runtime system. The runtime system can be triggered to load an dynamic aspect at runtime via an POSIX signal. It then expects the filename of the DSO implementing the dynamic aspect to be written to a fifo socket and then dynamically weaves the aspect.

The marker postprocessor

As explained in our paper, introduction of non-static members are problematic. At compilation time of the instrumented program, introductions of dynamic aspects cannot be known. Still the AspectC++ language allows introduction of non-static members, and we want to support that feature in dac++ as well. In order to do this, we statically weave in an extension pointer into each type in that a dynamic aspect can potentially introduce members at compilation time of the program. The introduction itself is then implemented using indirection at runtime.

This however leaves the problem of using the correct syntax to access introduced members. Introduced members can only be accessed from extension modules, that is the module implementing the dynamic aspect. We are using ac++ to detect the source code locations in the code and fix them to use the indirection over the introduced pointer. That's where the postprocesser comes in: It rewrites the marked locations accordingly.

Dynamic Aspects

In the paper, we implemented two dynamic aspects in the AspectC++ language: $Header: /home/inf4/tartler/.www4/dac/RCS/index.html,v 1.1 2008/10/21 07:21:45 tartler Exp $

Related projects