Instrumenting Code for the Target

BITCOV instrumentation is put into effect by configuring the ctc.ini.

In the block of the cross-compiler used, put:

RUN_AFTER_INSTR = ctc2static

With that setting, a script called ctc2static is run after ctc has instrumented the source code. This script performs two tasks:

  • Changes the way the code is instrumented.
  • Maintains an auxiliary file with default name MON.aux, which is needed later to resolve the CTC_array offsets to individual files and to their specific probe locations. The file naming follows the symbol file naming.

The three BITCOV variants are used as follows (typical cases, with ctcwrap as an example):

BITCOV

ctcwrap -i m -v xmake -f targprog.mak all

Technically the CTC_array[] is an array of bytes (unsigned char), which is handled as a tight bit vector in memory, one bit per measurement point is used.

BYTECOV

ctcwrap -i m -v –C OPT_ADD_COMPILE+-DCTC_BYTECOV \
xmake -f targprog.mak all

The CTC_array[] elements are bytes (unsigned char), which carry the "executed" (1) / "not executed" (0) information, one byte per measurement point is used.

With actual counters

ctcwrap -i m -v –C OPT_ADD_COMPILE+-DCTC_NO_BITS \
-C “OPT_ADD_COMPILE+-DCTC_COUNTER=unsigned int” xmake -f targprog.mak all

The CTC_array[] elements are of type unsigned int and carry the number of execution hits (0, 1, 2, 3,…); one word is used per measurement point.

The OPT_ADD_COMPILE+… settings can be edited also permanently in the ctc.ini configuration file in the cross-compiler block.

General Considerations

All source files must be instrumented in the same variant described above.

Timing instrumentation can not be used with these variants. The source files can be instrumented individually with regard to instrumentation mode.

In the CTC_array[] vector the instrumented files use their own coverage data slices in the order they have been instrumented. Partly from this, the following technical usage constraints exist:

  • All code files have to be instrumented only once. The instrumentation must result in only one symbol file and one auxiliary file.
  • If some code file is changed and needs to be instrumented again, you need to do a full rebuild, delete the .sym and .aux files and instrument all files again.

When all files have been instrumented for the first time, the work is not yet done. You have to define the variable CTC_array[] in some compilation unit. Also, you have to figure out what the required size for CTC_array[] is. This can be done as follows:

From the instrumentation a symbol file was created, by default called MON.sym. Issue command

ctcpost –L MON.sym | any2mem

To the screen you get a line, something like:

unsigned char CTC_array[27] = {0};

For BITCOV variant, 27 bytes (216 bits) are needed to record the 0/1 coverage information and the line above can be used directly.

For BYTECOV and for actual counters, an array of size 27*8=216 is needed.

With the calculated size, the array must be defined in one of the source code files, making sure that it is visible to all instrumented files.

If actual counters are used, the CTC_array type has to be changed:

unsigned int CTC_array[216] = {0};

Alternatively the used memory array address can be given also explicitly, e.g.:

ctcwrap -i m -v –C OPT_ADD_COMPILE+-DCTC_BYTECOV \
-C OPT_ADD_COMPILE+-DCTC_ARRAY=0X4200 xmake -f targprog.mak all

In this case you still have to use ctcpost and any2mem to find out how many measurement points are needed. As this example is Bytecov style, multiply by 8. Then do not edit or allocate CTC_array[] anywhere. Instead, you need to arrange that at absolute memory location starting from address 0X4200 there are enough 0-initialized bytes. The coverage data comes to that memory area.

Note: Testwell CTC++ specific pragmas affecting CTC runtime can not be used in any BITCOV variant. Pragmas with instructions towards instrumentation like #pragma CTC SKIP, #pragma CTC ENDSKIP or #pragma CTC ANNOTATION can be used even in BITCOV workflows.