Debugging and Profiling C++ Template Metaprograms
C++ Template Metaprogramming is a well known technique in which clever definitions of templates can force the C++ compiler to execute algorithms at compilation time. Among the application areas of template metaprograms are the expression templates, static interface checking, code optimization with adaption, domain specific language embedding and active libraries. C++11 introduced some new features to make template metaprogramming even more attractive.
Despite its importance there are surprisingly few tools for supporting the design, maintenance and analysis of C++ template metaprograms. The radically increased compilation time of programs using template-heavy code is one of the phenomena of whose root is a serious challenge to trace down. The lack of usable debugger and profiler tools hinders the wider usage of template metaprograms.
Based on our earlier experience we have developed a template metaprogram debugger and profiler prototype toolset. The aim of the toolset is to provide support for developers and maintainers who work on large C++ source base with heavy usage of C++ templates. The toolset could be particularly interesting for programmers who are investigating bugs and compilation bottlenecks regarding C++ template metaprograms.
The toolset has been built on top of the llvm/clang open source C++ compiler infrastructure. Capturing the most critical template related compiler actions the tool emits a xml format trace file to record the “instantiation stack” of the program. Every entry in this file represents the beginning or the end of template instantiation events. An entry contains the type of the event in clang specific way. Further information is the name of the template to instantiate, and the position of the code snippet which induced the instantiation (this is typically the caller). Information relevant to profiling is a time stamp, which contains the time of the instantiation (this is wall time) and actual memory usage. As memory profiling is time and resource consuming, it can be switched off. To minimize distortion of profiling we keep this information in an internal buffer and delay the generation of the xml trace file. According to our measures time distortion is less than 3% on practical examples.
We developed a Qt based frontend to visualize the results stored in the trace file. The frontend has a source code view similar to run-time debuggers, where the user can set breakpoints and can replay instantiations step by step or in a fast forward/backward way. Uninteresting instantiations can be excluded from the visualization based on regular expressions. Another view is the profiling information with instantiation time and optional memory usage. Finally we draw instantiation graph which expresses the instantiation dependencies and animates the instantiation steps.
Speaker: Zoltan Porkolab