In this section
Introduction
C/C++test ships with the cpptestcc
– an standalone coverage tool that allow you to collect coverage information for any kind of application. Collecting coverage information with cpptestcc
involves three phases:
- Instrumenting the application by integrating the
cpptestcc
tool into your build. - Executing instrumented code to create the
.clog
file that contains coverage data. - Reviewing the coverage information by importing the
.clog
file into C/C++test with a C/C++test's built-in test configuration.
See Runtime Error Detection for information about how to collect application coverage when performing runtime error detection with C/C++test.
Quick Start with cpptestcc
Integrate the cpptestcc tool with your build system by using it as a prefix in the compilation command line. For example, your command line may resemble the following:
cpptestcc -compiler gcc_3_4 -line-coverage -workspace /home/test/proj/cov -- cc -I app/includes -D defines -c source.cpp
- Build the instrumented application.
- Run the instrumented application. After the instrumented application finishes execution, the coverage data is stored in a
.clog
file. - In your IDE, create a new project that includes all the source files of the application.
Ensure that the files and all the paths remain unchanged. - Select the project and choose Parasoft> Test Configurations> Utilities> Load Application Coverage from your IDE menu to import the
.clog
file. - Review the coverage information (see Reviewing Coverage Information).
Instrumenting and Building Source Code
Three steps are performed during this phase:
- Source code is instrumented.
- Instrumented source code is compiled to the object file.
- All instrumented and non-instrumented objects are linked to the code coverage tool library, as well as any additional libraries required to form the final testable binary artifact.
These steps are typically performed during the build process and require that the coverage tool be integrated with the user build system. The cpptestcc
tool instruments the source code and compiles it into the object file. The cpptestcc
is designed to be used as a compiler prefix in compilation command lines.
Original compilation command line:
cc -I app/includes -D defines -c source.cpp
Coverage mode compilation command line:
cpptestcc -compiler gcc_3_4 -line-coverage -workspace /home/test/proj/cov -- cc -I app/includes -D defines -c source.cpp
When the coverage mode compilation command line is executed, cpptestcc
performs the following operations:
- Compilation command line is analyzed to extract information about source files
- All detected source files are parsed and instrumented for coverage metrics
- Instrumented files are reconstructed in the specified location using the
-workspace
switch; additional information about the code structure used during report generation is also stored - Compilation command line is modified and the original source files are substituted with instrumented versions
- Compilation command line is executed, object(s) files are created in the same location as in case of original command line
You can add the [INSTALL_DIR]/bin
directory to your PATH variable so that you do not have to use full paths when specifying the cpptestcc
command. All examples in this documentation assume this has been done.
The following pattern describes the syntax for coverage instrumentation:
cpptestcc -compiler <compiler configuration> <coverage metric specification> -workspace <workspace directory> -- <compilation command line>
<compiler configuration>
refers to a supported compiler configuration, e.g., gcc_3_4; see Supported Compilers for the list of supported compilers.<coverage metric specification>
refers to a supported coverage metric, e.g., line-coverage. See Command Line Reference for cpptestcc for the list of supported coverage metrics.- The
cpptestcc
command line is separated from compiler command line with the--
separator.
Linking Instrumented Code
The original linker command must be modified to include the additional library required by the code coverage instrumentation. The following example shows how this is typically accomplished:
Original compilation command line:
lxx -L app/lib app/source.o -lsomelib -o app.exe
Coverage mode compilation command line:
lxx -L app/lib app/source.o somelib.lib <coverage tool>/runtime/lib/cpptest.lib -o app.exe
Executing Instrumented Code
Details of the execution environment depend on the application specifics, but the coverage tool imposes the following limited dependencies on execution:
- If the coverage tool library was linked as a shared (dynamic-load) library, then you must ensure that the library can be loaded when instrumented application is started. On Windows, this typically requires adding
[INSTALL_DIR]/bin
directory to the PATH environment variable. On Linux systems, add[INSTALL_DIR]/runtime/lib
to the LD_LIBRARY_PATH variable. - If the coverage results transport channel was modified, all requirements resulting from the modification have to be fulfilled. For example, if results are sent through TCP/IP socket or rs232 then appropriate listening agents need to be started before the instrumented application executes.
After the instrumented application finishes execution, the collected results must be stored in the file that will be used for report generation.
Generating Reports
Final coverage report is generated from two types of information:
- Code structure information generated by
cpptestcc
during build process (stored in workspace) - Coverage results achieved from instrumented code execution
Coverage report can be generated in an HTML format or sent to DTP Server. The following example shows the command for generating a report:
cpptestcli -config builtin://Coverage -input cpptest_results.clog -workspace /home/test/proj/cov
In order to properly merge coverage data in DTP, you must specify one or more coverage image tags in the command line or .properties settings file. The coverage image(s) is automatically sent to the connected DTP server where it can be associated with a filter.
You can specify a set of up to three tags that can be used to create coverage images in DTP Server with the report.coverage.images
property:
report.coverage.images=[tag1; tag2; tag3]
Associate coverage images in DTP in the Report Center administration page (administration> Projects> Filters> [click on a filter]).
You can also use the report.coverage.limit
property to specify a lower coverage threshold:
report.coverage.limit=[value]
Coverage results lower than this value are highlighted in the report. The default value is 40
.
Usage Example
In this example, the following code is from a c++ source file called main.c
:
#include <iostream> int main(int argc, char ** argv) { if (argc > 1) { std::cout << "Thank you for arguments" << std::endl; } else { std::cout << "Provide some arguments please !" << std::endl; } return 0; }
The normal file compilation command is gcc
:
g++ -c main.c -o main.o
To instrument this file and compile the instrumented code to the object file, the compilation command line must include the cpptestcc
command prefix:
cpptestcc -compiler gcc_3_4 -line-coverage -workspace /home/test/proj/cov -- g++ -c main.c -o main.o
Two artifacts are created as s a result of the cpptestcc command invocation:
- an object with instrumented code
- code structure information stored in the directory specified with
-workspace
option
Once the source file is instrumented and compiled to the object file it, can be linked to form the final executable. Normally this simple example would be linked with the following command:
g++ main.o -o app.exe
Coverage instrumentation requires additional library so the linking command line needs to look as follows:
g++ main.o <coverage tool install dir>/runtime/lib/cpptest.a -o app.exe
In this example, the static version of the coverage library was used. The dynamic/shared version, as well as the source code, is also provided for building a customized version. For additional information, see Code Coverage Runtime Library.
Once the application is linked it can be executed to collect information about code coverage. Run the following command:
./app.exe
The application will output the coverage log file, named cpptest_results.clog
by default, in the current work directory.
Finally, generate the report using the following command:
cpptestcli -config builtin://Coverage -workspace /home/test/proj/cov -input cpptest_results.clog -report report_dir
A report directory will be created containing the HTML report with code coverage information.
Using Coverage Tool for Complex Projects
The examples in this section describe several classes of projects and ways to approach integrating C/C++test.
Build includes compilation of multiple source files without static or dynamic libraries.
Compilation phase:
For all sources files or selected subsets, compilation should be prefixed withcpptestcc
tool with options for enabling the desired coverage metrics.
Linking phase:
The linker command line should be modified to include the coverage tool library. In most of the cases, you will include the static library:g++ source1.o source2.o <cov tool install dir>/runtime/lib/cpptest.a
- Build includes compilation of multiple source files and the preparation of multiple static libraries, which are linked to the main objects.
Compilation phase:
For all sources files or selected subsets, compilation should be prefixed withcpptestcc
tool with options for enabling desired coverage metrics. If coverage from static libraries should also be collected, they need to be instrumented, as well.
Linking phase:
The linker command line should be modified to include the coverage tool library. In most of the cases, you will include the static library. It is important to add the coverage tool library only once, usually during executable linking. Static libraries created during the build should not contain the coverage library. - Build includes compilation of multiple source files and preparation of multiple dynamic/shared libraries which are linked with main objects.
Compilation phase:
For all sources files or selected subsets, compilation should be prefixed withcpptestcc
tool with options for enabling desired coverage metrics. If coverage from dynamic libraries should also be collected, they need to be instrumented, as well.
Linking phase:
- Linking command lines for dynamic libraries should be modified to include the coverage tool shared/dynamic-load library.
- Linking command lines for static libraries should not be modified.
- Linking command line for executable should be modified to include coverage tool shared/dynamic library - Build includes the following:
- Compilation of multiple source files
- Preparation of multiple dynamic/shared libraries linked with main objects
- Multiple static libraries linked with main objects
Compilation phase:
For all sources files or selected subsets, compilation should be prefixed withcpptestcc
tool with options for enabling desired coverage metrics. If coverage from dynamic or shared libraries should also be collected, they need to be instrumented, as well.
Linking phase:
- Linking command lines for dynamic libraries should be modified to include the coverage tool shared/dynamic-load library.
- Linking command lines for static libraries should not be modified.
- Linking command line for executable should be modified to include coverage tool shared/dynamic library
Code Coverage Runtime Library Introduction
The C/C++test runtime library is a collection of helper functions and services used by source code instrumentation to emit coverage information at application runtime. Instrumented applications cannot be linked without the library. The runtime library can be linked to the final testable binary in multiple ways depending on tested project type.
In addition to providing basic services for instrumented code, the library is also used to adapt the code coverage solution to particular development environments, such as supporting non-standard transport for coverage results between tested embedded device and development host.
Pre-built Versions and Customized Builds
C/C++test ships with pre-built versions of the runtime library, which are suitable for use on the same platform on which CCE is installed. In most of the cases, collecting code coverage information from natively developed applications (i.e., MS Windows or Linux x86 and x86-64) can use pre-built versions of the runtime library.
All users developing cross-platform applications will need to prepare a custom build of the runtime library using a suitable cross compiler and possibly linker. Source code of the code coverage runtime library is shipped with CCE.
The process of preparing the runtime library custom build is typically limited to the compilation of runtime library source code. In some situations, you may need to install some fragments of source code to adapt code coverage to a particular development platform. This process is described in the following sections.
Using the Pre-built Runtime Library
The following binary files are included with the C/C++test:
Windows (x86 and x86-64)
File | Description |
---|---|
[INSTALL_DIR]/runtime/lib/cpptest.a | 32-bit static archive to be used with Cygwin GNU GCC compilers. To be added to linking command line |
[INSTALL_DIR]/runtime/lib/cpptest.lib | 32-bit import library to be used with Microsoft CL compilers. To be added to linking command line |
[INSTALL_DIR]runtime/lib/cpptes64.lib | 64-bit import library to be used with Microsoft CL compilers. To be added to linking command line |
[INSTALL_DIR]/bin/cpptest.dll | 32-bit Dynamic-link library to be used with Microsoft CL compilers. [INSTALL_DIR]/bin should be added to PATH environmental variable |
[INSTALL_DIR]/bin/cpptest64.dll | 64-bit Dynamic-link library to be used with Microsoft CL compilers. [INSTALL_DIR]/bin should be added to PATH environmental variable |
Linux (x86 and x86-64)
File | Description |
---|---|
[INSTALL_DIR]/runtime/lib/libcpptest.so | 32-bit shared library. To be added linking command line. [INSTALL_DIR]/runtime/lib should be added to LD_LIBRARY_PATH |
[INSTALL_DIR]/runtime/lib/libcpptest64.so | 64 bit shared library. To be added linking command line. [INSTALL_DIR]/runtime/lib should be added to LD_LIBRARY_PATH |
If you need to use the runtime library in a form not provided as an out-of-the-box solution, prepare a custom build of the runtime library that matches specific development environment requirements. For more details, see Customizing the Runtime Library.
Integrating with the Linker Command Line
Integrating the C/C++test runtime library with a tested application linking process usually requires modifying the linker command line and, in some cases, the execution environment. This section describes how to modify the linking process when using the pre-built versions shipped with C/C++test.
Static library for Windows Cygwin GNU GCC compilers:
- Locate the linker command line in your build scripts
- Modify the build scripts so that the coverage runtime library is specified somewhere in the linker command line--preferably after all object files.
Dynamic-link library for MS CL compilers:
- Locate the linker command line in your build scripts
Modify the build scripts so that the coverage runtime library is specified somewhere in the linker command line--preferably after all object files. For example:
$(LXX) $(PRODUCT_OBJ) $(OFLAG_EXE)$(PROJ_EXECUTABLE) $(LXXFLAGS) $(SYSLIB) $(EXECUTABLE_LIB_LXX_OPTS) <INSTALL>/runtime/lib/cpptest.lib
Make sure that the
[INSTALL_DIR]/bin
directory is added to your PATH environment variable so that the library can be located when the tested program is started. You may also consider copyingcpptest.dll
(orcpptest64.dll
) file to the same directory as your executable file or to another location that is scanned for dynamic-link libraries during tested application startup.
Shared library for Linux GNU GCC compilers:
- Locate the linker command line in your build scripts
Modify the build scripts so that the coverage runtime library is specified somewhere in the linker command line--preferably after all object files. For example:
$(LXX) $(PRODUCT_OBJ) $(OFLAG_EXE)$(PROJ_EXECUTABLE) $(LXXFLAGS) $(SYSLIB) $(EXECUTABLE_LIB_LXX_OPTS) -L <INSTALL>/runtime/lib -lcpptest
Note the addition of the
-L [INSTALL_DIR]/runtime/lib
and-lcpptest
options.- Make sure that shared library can be found by tested executable by modifying LD_LIBRARY_PATH environmental variable to include [INSTALL_DIR]/runtime/lib location.
Customizing the Runtime Library
You may need to customize the runtime library as a result of the following conditions:
- Different form of binary file is required
- Enabling a non-default communication channel for results transport
- Installing custom implementation of communication channel for results transport
- Enabling a non-default support for multithreaded applications
- Installing custom implementation of support for multithreaded applications
Library Source Code Structure
The runtime library source code is shipped with C/C++test in the [INSTALL_DIR]/runtime
directory. The following table describes the structure:
Component | Description |
---|---|
include | Directory that contains the library include files. |
src | Directory that contains the library source code. |
Makefile | Basic Makefile provided for building the runtime library. |
target | Directory that contains a set of Makefile include files with compiler specific options for preparing runtime library builds for most popular development environments. |
channel | Directory that contains a set of Makefile include files with configuration for supported communication channels. |
Switching Communication Channel Support
The runtime library supports data collection through various communication channels. The communication channel used depends on the development environment. In most cases, storing results in a file or files is appropriate, but in other TCP/IP sockets or RS232 transport may be required. Specific communication channels can be enabled by setting the value to a dedicated macro during cpptest.c
library source file compilation. Add -D<MACRO> to the compilation command line to set the value. The following table provides the full list of communication channel control macros:
Channel | Description |
---|---|
CPPTEST_NULL_COMMUNICATION | Empty implementation. If enabled no results will be sent. Suitable for initial test builds and debugging. |
CPPTEST_FILE_COMMUNICATION | File-based implementation. ANSI C File I/O interface is used. If enabled, results will be written to a local drive file. The following additional configuration macros are also provided:
|
CPPTEST_SPLIT_FILE_COMMUNICATION | File-based implementation. ANSI C File I/O interface is used. If enabled, results will be written into a series of local drive files. You can configure this channel with the following macros:
To pass the series to
|
CPPTEST_UNIX_SOCKET_COMMUNICATION | TCP/IP socket based implementation. POSIX API is used. If enabled results are sent to the specified TCP/IP port. The following additional configuration macros are provided:
|
CPPTEST_WIN_SOCKET_COMMUNICATION | As above, MS Windows API is used. |
CPPTEST_UNIX_SOCKET_UDP_COMMUNICATION | As above, UDP based implementation. |
CPPTEST_RS232_UNIX_COMMUNICATION | RS232 based implementation. POSIX API is used. If enabled then results are sent via the specified RS232 system device. The following additional configuration macros are provided:
|
CPPTEST_RS232_WIN_COMMUNICATION | As above. MS Windows API is used. |
CPPTEST_RS232_STM32F103ZE_COMMUNICATION | STM32F103x USART based implementation. STM Cortex library interface is used (ST/STM32F10x/stm32f10x.h header file is required) |
CPPTEST_HEW_SIMIO_COMMUNICATION | Renesas HEW simulator specific implementation. |
CPPTEST_LAUTERBACH_FDX_COMMUNICATION | Lauterbach TRACE32 based implementation (FDX used) |
CPPTEST_ITM_COMMUNICATION | ARM CoreSight ITM unit based communication. Requires CMSIS header files. |
CPPTEST_CUSTOM_COMMUNICATION | Enables empty template for custom implementation |
If the runtime library is being built with the provided Makefile, then one of the make configuration files provided in the [INSTALL_DIR]/runtime/channel
directory can be used. See Integrating with Make-based Build Systems for details.
Installing Support for Custom Communication Channel
If none of the communication channel implementations fit into your development environment, then a custom implementation can be provided. The following instructions describe how to customize the runtime library so that it uses a custom implementation of a communication channel:
- Make a copy of
[INSTALL_DIR]/runtime/src/cpptest.c
and open the file for editing. Locate the section 1.13 "Custom Communication Implementation.
The custom communication implementation section contains empty templates for four different methods:Function Description void cpptestInitializeStream(void)
This function is responsible initializing the communication channel, for example creating and connecting to a socket or the initialization of UART device. void cpptestFinalizeStream(void)
This function is responsible for finalizing the communication channel. For example, it may be responsible for closing TCP/IP socket. int cpptestSendData(const char *data, unsigned size)
This function is responsible for sending size bytes from a data buffer. void cpptestFlushData(void)
This function is responsible for flushing the data. Its meaning depends on the particular transport type. It may have a limited application in some implementations. In this case, it should be left empty. - Provide the implementation for these methods that match your environment requirements.
- Compile
cpptest.c
with the following macro definition added to compilation command line:"-DCPPTEST_CUSTOM_COMMUNICATION"
- If the generated object file is insufficient, you can process the file even further to meet your needs (e.g., to create a shared library).
Switching Multithreading API Support
The runtime library contains support for multithreaded applications. POSIX, MS Windows, and VxWorks APIs are supported. You can enable support for a specific multithreading API by adding -D<MACRO>
to the compilation command line during cpptest.c
compilation. The following table describes the full list of multithreading API support control macros:
Macro | Description |
---|---|
CPPTEST_NO_THREADS | Empty implementation. Coverage runtime is not prepared to be used together with multithreaded applications |
CPPTEST_WINDOWS_THREADS | MS Windows multithreading API implementation |
CPPTEST_UNIX_THREADS | POSIX multithreading API implementation |
CPPTEST_VXWORKS_THREADS | VxWorks multithreading API implementation |
Installing Support for Custom Threading API
If you are using C/C++test with multithreaded applications that do not use a supported multithreading API, you can customize the runtime library to work with your multithreading API. There are following steps required:
- Make a copy of
[INSTALL_DIR]/runtime/src/cpptest.c
and open the file for editing Locate the section 2.5 "Custom Multithreading Implementation"
Custom multithreading implementation section contains empty templates for two different methods:Function Description static int cpptestLock(void)
This function ensures synchronized operations inside the coverage tool runtime library. If a thread locks access to the runtime library service, it means an atomic operation is in progress and no other thread can use runtime library services. Once the lock is released other threads can use runtime library services static int cpptestUnlock(void)
Releases the lock on runtime library services. Provide the implementation for the methods that matches your environment requirements.
Compile
cpptest.c
with the following macro added to compilation command line:"-DCPPTEST_CUSTOM_THREADS"
If the generated object file is insufficient, you can process the file even further to meet your needs (e.g., to create a shared library).
Building the Runtime Library
C/C++test ships with a simple Makefile (see Library Source Code Structure) which simplifies the process of building the runtime library. In many instances, however, the make file provided will not be required because the source code is already optimized for the building process. The only step that is always required is the compilation of the main cpptest.c
source file. Any additional processing of the produced object file will depend on the particular development environment and its requirements, such as providing the runtime library as a shared library.
Building the Runtime Library Using the Provided Makefile
- Change directory to
[INSTALL_DIR]/runtime
. - If compilation flags need to be modified (e.g., adding specific cross-compiler specific or definitions to enforce runtime library reconfiguration), provide a new make configuration file in the target subdirectory. For convenience, copy one of the existing target configuration files and modify its contents to fit your needs.
- Invoke the following command line:
make TARGET_CFG=<target config file name> CHANNEL=<channel config file name>
- A
build
subdirectory will be created with a single objectcpptest.<OBJ_EXT>
, which can be used to link with instrumented application. - If the coverage runtime library needs to be linked to from a shared library, dynamic link library, or any other type of binary, the Makefile needs to be customized for this purpose or a custom build needs to be setup.
User Build of the Runtime Library
To setup a user build of coverage tool runtime library perform the following steps:
- Copy the cpptest.c file from
[INSTALL_DIR]/runtime/src/cpptest.c
to your preferred location. - Introduce any customizations as described in Customizing the Runtime Library.
- Set up a build system of your preference (e.g., IAR Embedded Workbench project or any other type of source code builder).
- Modify the compilation flags to contain the compiler include a flag (typically
-I
) with the following value:-I[INSTALL_DIR]/runtime/include
- Add any required configuration defines (typically
-D)
, for example:-DCPPTEST_FILE_COMMUNICATION -DCPPTEST_NO_THREADS
- Invoke the command to run your builder (for example, select build command in the IDE).
- Locate the resulting object file and use it to link with your instrumented application.