This is a small source repository to simplify the code coverage tasks on embedded systems.
#Directory structure
gcov: code coverage librarysample/rtems: sample code for RTEMS operating systemgdb: gdb script to automate the code coverage counters retrieval
#Usage
Let us take the sample code inside sample/rtems. This folder contains two
files. One file bubble.c that is the software we want to profile and, a
wrapper.c that wraps the main function to ensure the code coverage counters
are transmitted back to the host.
In the case of RTEMS, the main function is called Init. The wrapper method
__wrap_Init() wraps that function to ensure __gcov_exit() is called when
finished.
extern void __real_Init(void *ignored);
#define real_function __real_Init
void __wrap_Init(void *ignored)
{
printf("%s: Coverage initialized\n", __func__);
/* call the real funcion */
real_function(ignored);
// Send the gathered coverage info
__gcov_exit();
// These lines here bellow are not really important as are specific of RTEMS OS
printf("rtems_task_delete\n");
rtems_task_delete( RTEMS_SELF );
}##Profiling in 3 steps
First, we need to compile the source files on which we want to perform the code
coverage. For that we'll include the flags -ftest-coverage and
-fprofile-arcs to tell GCC to instrument the code.
${CROSS-COMPILE}-gcc -c sample/bubble.c -ftest-coverage -fprofile-arcs
where CROSS-COMPILE is the prefix for your GCC cross compiler (in this case
would be spar-rtems-)
Second, compile the rest of our project and wrap if necessary our application
entry point. In this case the Init function.
${CROSS-COMPILE}-gcc -g -o bubble bubble.o sample/wrapper.c gcov/* -Xlinker --wrap -Xlinker Init -I./gcov
Third, we can use GDB to connect to our embedded hardware and let it receive the coverage profile information.
The following code is an example of a possible GDB script that could be used.
tar extended-remote :10001
load bubble.cov
b base.c:85 # break on coverage_helper_breakme() function
commands 1
silent
set $filename = tmp->info->filename
set $dataBegin = buffer
set $dataEnd = buffer + sizeInBytes
eval "dump binary memory %s 0x%lx 0x%lx", $dataBegin, $dataEnd, $filename
eval "echo dump binary memory %s 0x%lx 0x%lx", $dataBegin, $dataEnd, $filename
echo \n
c
end
c
Now, just use GDB to connect to your target hardware and execute your application
gdb -x gdb/automate_coverage.gdb bubble
The corresponding .gcda files with the information about the code coverage should have been created. You can now process them using lcov at will.