platform-espressif32 icon indicating copy to clipboard operation
platform-espressif32 copied to clipboard

Support for using gcov to measure coverage?

Open 5p4k opened this issue 1 year ago • 3 comments

ESP-IDF has support for gcov coverage data (see also here). It can be collected through JTAG.

I've tried to make this work with platformio but I believe this is not possible at the moment. This is what would be necessary:

  1. set some options in sdkconfig (easily done in platformio too with pio run -t menuconfig)
  2. add the --coverage compile option and link against gcov. This is possible in platformio by adding --coverage -lgcov to build_flags, however in my use case, I added --coverage only to the library I intend to cover (by editing library.json).
    However, this is the first roadblock: how do I go about adding --coverage only to a subset of sources? It looks like adding to the CMakeLists.txt some set_source_files_properties commands does not work. How are the compile flags assembled? By parsing a subset of the CMakeLists?
  3. Connect with JTAG and issue an esp gcov dump command. This does not work with platformio:
Total trace memory: 16384 bytes
Connect targets...
[esp32s3.cpu0] Target halted, PC=0x40378AD6, debug_reason=00000000
Set GDB target to 'esp32s3.cpu0'
[esp32s3.cpu1] Target halted, PC=0x40378AD6, debug_reason=00000000
Targets connected.
Data timeout!
Failed to poll target for gcov data (-4)!
Disconnect targets...
[esp32s3.cpu0] Target halted, PC=0x40378AD6, debug_reason=00000000
Set GDB target to 'esp32s3.cpu0'
[esp32s3.cpu1] Target halted, PC=0x40378AD6, debug_reason=00000000
Targets disconnected.

What I tried

I've looked at the output of pio run -vvv to identify discrepancies to idf.py -v build, and the link command that creates firmware.elf differs by quite some options.

One thing that might be related is the lack of esp-idf/app_trace/libgcov_rtio.a and -Wl,--wrap=__gcov_init in the platformio link command.

It seems that IDF generates the libgcov_rtio.a by running the following command:

# IDF command
xtensa-esp32s3-elf-objcopy \
    --redefine-syms $HOME/esp-idf/components/app_trace/gcov/io_sym.map \
    $HOME/.espressif/tools/xtensa-esp32s3-elf/esp-12.2.0_20230208/xtensa-esp32s3-elf/lib/gcc/xtensa-esp32s3-elf/12.2.0/libgcov.a \
    libgcov_rtio.a

In a platformio build, this is missing and libgcvo_rtio.a is not present in .pio/build/<ENV>/app_trace. However, platformio compiles some gcov_rtio.c file and bundles it in libapp_trace.a:

# PIO command
xtensa-esp32s3-elf-ar \
    rc \
    .pio/build/esp32s3/esp-idf/app_trace/libapp_trace.a \
    .pio/build/esp32s3/app_trace/app_trace.o \
    .pio/build/esp32s3/app_trace/app_trace_util.o \
    .pio/build/esp32s3/app_trace/host_file_io.o \
    .pio/build/esp32s3/app_trace/gcov/gcov_rtio.o \
    .pio/build/esp32s3/app_trace/port/port_uart.o

and the latter libapp_trace.a is indeed linked into firmware.elf.

I tried adding -Wl,--wrap=__gcov_init to the build flags, but the linker fails with

/home/spak/.platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/11.2.0/../../../../xtensa-esp32s3-elf/bin/ld: .pio/build/esp32s3/src/main.o:(.literal._sub_I_00100_0+0x4): undefined reference to `__wrap___gcov_init'
/home/spak/.platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/11.2.0/../../../../xtensa-esp32s3-elf/bin/ld: .pio/build/esp32s3/src/main.o: in function `_sub_I_00100_0':
main.cpp:(.text._sub_I_00100_0+0x6): undefined reference to `__wrap___gcov_init'

So I am not sure what else could be tried. Perhaps there are symbols that should be extracted from the IDF-bundled libgcov.a and that is missing?

In general it's not very clear to me how platform-espressif32 interacts with IDF in the build process. Wouldn't it be better to simply call idf.py build and remap the build folder to .pio to retain all functionalities offered by idf.py through CMake?

5p4k avatar Sep 18 '23 11:09 5p4k

It also seems that esp-idf/components/app_trace/gcov/io_sym.map is absent from ~/.platformio/packages/framework-espidf/components/app_trace/gcov. The contents of that file are

fopen          gcov_rtio_fopen
fclose         gcov_rtio_fclose
fwrite         gcov_rtio_fwrite
fread          gcov_rtio_fread
fseek          gcov_rtio_fseek
ftell          gcov_rtio_ftell
setbuf         gcov_rtio_setbuf

5p4k avatar Sep 18 '23 12:09 5p4k

There is a NASA project that I've used to collect gcov data on an esp32 in combination with the WOKWI emulator. You can check it out my attempt here; https://github.com/mp-se/wokwi-gcov.

It would be great if this is a feature that is included as a feature in platformio and not just the native gcov target.

mp-se avatar Nov 10 '23 07:11 mp-se

This issue has been automatically marked as stale because it has not had recent activity. Please provide more details or it will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Dec 15 '23 06:12 stale[bot]