C/C++ Instrumentation#

Prerequisites#

Instrumentation for C and C++ is packaged with the C++ SDK. Instrumentation is supported by the header file antithesis_instrumentation.h. This file must be included in one, and only one translation unit at link time. Coverage instrumentation requires Clang 13 or higher, and either C++ 11 or higher or C89 or higher.

We recommended that you include the instrumentation header in the file where you define the main function, as follows:

#include "antithesis_instrumentation.h"

Note

If you are unable to meet the requirements of our C/C++ instrumentation, perhaps because you use an older version of Clang or are unable to include a header file, then you can try our legacy instrumentation approach. This approach does not require a modern Clang or a header file, but it will instead require you to provide a shared object at link-time.

Build Requirements#

Add the following compile flag:

-fsanitize-coverage=trace-pc-guard -g

And add the following link flag:

--build-id

If your build process includes a single compile/link step, then add both compile and link flags with the following:

-fsanitize-coverage=trace-pc-guard -g -Wl,--build-id

Note

We recommend the use of -g but it is not necessary. It will provide more detailed information when bugs are found, which may make debugging easier.

Validation#

To confirm that the instrumentation process was successful, you can run the command nm to list all the symbols in a binary, and then grep the string “antithesis_load_libvoidstar” .

$ nm client_binary | grep "antithesis_load_libvoidstar"
T antithesis_load_libvoidstar

Notice the “T” character in the previous code block: it means the symbol is in the text (code) section.

If this does not work you probably failed to include the header file.

Symbolization#

The LLVM compiler infrastructure will output debug symbols in the DWARF format. These files should be copied into the configuration image at a path identical to the path at which its corresponding binary can be found in your software containers. For example, if you are compiling a C++ or Rust program called server and it usually runs in your container at /usr/bin/server, then the corresponding debug symbols (which could be separate debug info or just the original unstripped binary) should be copied to the configuration image at the path /usr/bin/server.

Help#

Contact us if you need help with this.