Generating a coverage report

Renode offers many execution tracing features, as described in the Execution tracing section, and allows you to dump the entire execution of a binary into a single file. With an execution trace of a properly built binary and a dedicated script it’s possible to create a code coverage report. The script combines data in the DWARF format (debug information available in ELF files, which are typically used to load software to Renode) with the number of executions of each instruction counted by Renode. The following tutorial will walk you through the steps necessary to generate such a report in Renode.


To generate a report, you need to have Renode installed along with the execution tracer script. On Linux you can simply download a portable package by following these instructions.

It’s assumed that you execute the rest of commands in the directory of the Renode package, otherwise you need to change the path to the appropriate installation location.

To run the script you need to first install the prerequisites:

python3 -m pip install -r tools/execution_tracer/requirements.txt

Building a binary

Renode can trace execution of a binary built in any way, but the script requires a binary with debug information in the DWARF format. To provide the best result it’s recommended to use the -g and -Og flags (for GCC) during compilation. Please note that different compilers may require different options.

The -g switch adds debug information to the binary, specifically code line numbers for each machine instruction. The script requires that information, so the lack of it causes an error.

The -Og switch disables most optimizations and is intended to make the debugging process easier. Any optimization done by a compiler may prevent some redundant lines of code from being executed. For the purpose of generating a coverage report, same as for debugging, it’s recommended to execute the code without any optimizations. Generating a report for an optimized binary may create imprecise or even unexpected results.

For the purpose of this tutorial we’ve prepared example code and a prebuilt binary. You can easily download them using the following commands:

wget -O main.elf 

Tracing execution

To trace execution of the binary from the previous section, you can simply use the RESC script below. You can also execute these commands manually in Monitor.


The script runs the binary prebuilt for the Kendryte K210 platform, but the mechanism is generic and works for all platforms.

include @scripts/single-node/kendryte_k210.resc

cpu1 CreateExecutionTracing "trace" $CWD/trace.bin.gz PC True True

emulation RunFor "0.017" # Run 1.7 million instructions (default performance is 100MIPS)

The crucial command is the one that initializes execution tracing, specifically CreateExecutionTracing. The Execution tracing section contains details on configuring the command. The script that generates the coverage report requires at least PCs (addresses of executed instructions) in the trace file.


Tracing an additional type of data may cause an increase in the size of the output file. It’s also recommended to use a binary format and compression by setting the fourth and fifth arguments to True, as shown above.

Generating the report

Finally, you can run the script that generates the report:

tools/execution_tracer/ --coverage main.elf --coverage-code main.c --coverage-output main.c.cov trace.bin.gz

The output file (main.c.cov) should start with the lines shown below. The number before the colon indicates the number of executions of each line.

    0:  #include <stdio.h
    0:	#include "bsp.h"
    0:	const int buf_size = 100;
   28:	void funB(int *buf, int b) {
 2828:		for (int i = 0; i < buf_size; i++) {
 2800:			buf[i] -= b;
    0:		}
   28:	}

Last update: 2024-04-19