Adding GNU Coverage Tools to Eclipse

The GNU tools include powerful utilities to collect coverage information. With coverage I know which lines of my code have been executed, which is a very useful test metric. The GNU coverage tools are commonly used for Linux applications. But to my surprise not much for embedded application development, mostly because it requires a few extra steps to have it available? Why not using free and powerful tools for improving software quality? This article explains how to install the GNU gcov tools into the Eclipse IDE.

gcov with Embedded Target

gcov with Embedded Target

Outline

Many Eclipse distributions come with the gcov integrated. In case your installed Eclipse does not have it installed, the following article describes how to install  GNU Coverage tools (gcov) for it.

In this tutorial, I’m using the NXP MCUXpresso IDE 10.0.0 (build 344) as an example. This IDE is Eclipse Neon based and uses the ‘GNU Tools for ARM Embedded Processors 5 – Q3 2016’ release. The steps described should work for any other Eclipse or ARM tools version with minor changes.

To use the GNU gcov in Eclipse, I need the following parts:

  1. Eclipse gcov plugins installed
  2. gcov and related binutils

I wrote several articles about using gcov for embedded targets (see the links section at the end of this article). With newer Eclipse versions and GNU tools available, I decided to write an update.

1. Installation of Eclipse GCov Integration

💡 This step is only necessary if the Eclipse IDE does not have the plugins already installed.

Use the menu Help > Install New Software, and then point to the update site for your Eclipse version. For example on of the earlier MCUXpresso IDE from NXP is Eclipse Neon based, so I’m using the following update site:

http://download.eclipse.org/releases/neon

Make sure your are using the matching update site, e.g. for the MCUXpresso IDE 11.2.1 it is:

Eclipse 2019-12 update site - http://download.eclipse.org/releases/2019-12/

Under the Linux Tools group, select and install the GCov Integration.

GCov Integration Installation

GCov Integration Installation

This adds ‘Profiling’ settings, accessible with the menu Window > Preferences > C/C++ > Profiling:

Profiling Preferences

Profiling Preferences

With the plugin installed, I’m able to use the coverage information generated and I can open the coverage files from Eclipse:

Coverage Files

Coverage Files

2. Binutils

Gcov plugin depends on several binutils (binary utilities) (such as gcov, addr2line, c++filt and nm).

💡 Make sure you are using matching binary utilities with your build system/compiler. Mixing binutils with different versions of other tools can have unpredictable side effects.

With my research I have found out that the following tools are required:

  • gcov: GNU coverage tool, read coverage files and present the data
  • addr2line: maps an application binary address to a source
  • nm: lists symbols from a file
  • c++filt: utility to deal with C++ name mangling
  • strings: lists printable strings from files
  • gprof: GNU profiling tool. Not needed for coverage. Listed for completeness or if you want to use profiling too.

On Windows I’m using the following batch file (update it to match your toolchain and IDE path):

# Batch file to check and copy the needed tools for gcov/gprof to be used in an Eclipse IDE
# Example for using MCUXpresso IDE
SET TOOLCHAIN_PATH=C:\nxp\MCUXpressoIDE_10.0.0_344\ide\tools\bin
SET IDE=C:\nxp\MCUXpressoIDE_10.0.0_344\ide\mcuxpressoide.exe

ECHO checking gcov/gprof dependencies on binutils
IF NOT EXIST "%TOOLCHAIN_PATH%\gcov.exe" COPY "%TOOLCHAIN_PATH%\arm-none-eabi-gcov.exe" "%TOOLCHAIN_PATH%\gcov.exe"
IF NOT EXIST "%TOOLCHAIN_PATH%\addr2line.exe" COPY "%TOOLCHAIN_PATH%\arm-none-eabi-addr2line.exe" "%TOOLCHAIN_PATH%\addr2line.exe"
IF NOT EXIST "%TOOLCHAIN_PATH%\nm.exe" COPY "%TOOLCHAIN_PATH%\arm-none-eabi-nm.exe" "%TOOLCHAIN_PATH%\nm.exe"
IF NOT EXIST "%TOOLCHAIN_PATH%\c++filt.exe" COPY "%TOOLCHAIN_PATH%\arm-none-eabi-c++filt.exe" "%TOOLCHAIN_PATH%\c++filt.exe"
IF NOT EXIST "%TOOLCHAIN_PATH%\strings.exe" COPY "%TOOLCHAIN_PATH%\arm-none-eabi-strings.exe" "%TOOLCHAIN_PATH%\strings.exe"
IF NOT EXIST "%TOOLCHAIN_PATH%\gprof.exe" COPY "%TOOLCHAIN_PATH%\arm-none-eabi-gprof.exe" "%TOOLCHAIN_PATH%\gprof.exe"

ECHO Extending PATH
SET PATH=%PATH%;%TOOLCHAIN_PATH%

ECHO Launching Eclipse IDE
"%IDE%"

It checks if the needed tools are present and copies them if needed.

coverage and related binutils

coverage and related binutils

It extends the system path to make sure they are found, and then launches the IDE with the new settings.

💡 I’m using that approach with a batch file as I don’t want to change the global system PATH variable (which would be a possibility).

Summary

Enabling gcov in Eclipse requires the plugins installed plus the matching gcov and binutils for the Eclipse IDE. For more detailed information how coverage works, see the links at the end of this article.

In a next article, I’m going to outline how to generate and collect coverage information in Eclipse.

Happy Covering 🙂

Links

19 thoughts on “Adding GNU Coverage Tools to Eclipse

  1. Pingback: GNU Code Coverage on Embedded Target with Eclipse Neon and ARM gcc 5 | MCU on Eclipse

  2. Hi Erich – rather than copying arm-none-eabi-addr2line.exe to addr2line.exe etc. can’t you just change the names/prefixes of the tools under Window > Preferences > C/C++ > Profiling > Binutils Preferences?

    You can probably even preconfigure these by putting the settings in a plugin_customization.ini file referenced by eclipse.ini:

    http://blog.vogella.com/2012/08/07/eclipse-papercut-9-default-preference-settings-via-plugin_customization-ini-type-filter-example/

    org.eclipse.linuxtools.binutils/PREFKEY_ADDR2LINE_CMD=arm-none-eabi-addr2line
    org.eclipse.linuxtools.binutils/PREFKEY_CPPFILT_CMD=arm-none-eabi-c++filt
    org.eclipse.linuxtools.binutils/PREFKEY_NM_CMD=arm-none-eabi-nm
    org.eclipse.linuxtools.binutils/PREFKEY_STRINGS_CMD=arm-none-eabi-strings

    Hope this helps.
    Regards
    Tommy

    Like

    • Hi Tommy,
      I considered changing the tool names in the Binutils preferences, but the problem is that this does not allow me to set the names for all the needed tools. So instead doing it in multiple places halfway, I decided to rename all of the tools. And that way it would not be a workspace setting which I would have to repeat for every workspace.

      Like

      • OK – I didn’t notice that not all of the relevant tools can be renamed in the GUI. That seems like a bit of an oversight in the Gcov configuration GUI. I understand now why you do it the way that you do. Thanks.

        Like

  3. Hi,

    First of all, thank you for yours articles. They help a lot.
    I am trying to have semihosting with a Cortex-M3, Eclipse, GNU Embedded GCC (7-2017-q4 and try with 5_2-2015q4) and the SEGGER J-Link Embedded probe. The “printf” function works well. But the “fopen” function returns 0 and does not create the file on the host. Have you an idea ? It seems that this probe support the file semihosting.
    Note: I have set the rdimon.specs but not the “newlib-nano” library, because if I set it the “printf” function does not work.

    Thanks

    Like

    • Thanks, good to hear that they are useful :-).
      Yes, the J-Link probes do support semihosting, and it is supported with the GNU Embedded GCC libraries. Make sure you use a recent (not old) J-Link driver (but I think Segger supports file I/O for more than 2 years).
      It works both with the newlib-nano and the newlib library. Nano is slower but uses less memory. One thought I have is that you should allocate plenty of heap and stack space (several KBytes) if you are using file I/O, same for using printf()).
      Maybe you were running into a heap/stack overflow? Allocate as much as you can for heap and stack.
      I hope this helps,
      Erich

      Like

      • I have installed the last driver and firmware into the probe.
        The MCU Embedded Eclipse plugin gives only the option to use newlib-nano (–specs=nano.spec).
        I have allocated 32KB of heap and 32KB of stack space.

        Like

        • Yes, in this case (only newlib), the printf works fine. But not this line: fopen(“c:\\tmp\\test.txt”, “w”) (the “c:\tmp” directory already exists). The fopen returns 0.
          Is it possible that it is a problem in the linker script ?
          No special pin of the JTAG cable is needed for file transfert ? (I believe that it is just a protocol with the GDB, right ?)

          Like

        • In my coverage library I’m checking with the following function if file I/O works:

          int gcov_check(void) {
          #if GCOV_DO_COVERAGE
          FILE *file = NULL;

          file = fopen ("c:\\tmp\\test.txt", "w");
          if (file!=NULL) {
          fputs("hello world with file I/O\r\n", file);
          (void)fwrite("hello\r\n", sizeof("hello\r\n")-1, 1, file);
          fclose(file);
          return 1; /* ok */
          }
          return 0; /* failed */
          #else
          return 1; /* ok */
          #endif
          }

          I don’t think it is an issue with the linker script, and no special JTAG/SWD pin is needed for semihosting. It works the way the the printf() code calls a breakpoint exception which is catched by the debugger (the debugger has to be attached/connected).
          I hope this helps,
          Erich

          Like

        • SEGGER sent me a answer :
          “As described, Semihosting is handled by the debugger, in this case GDB/GDB Server.
          Therefore the actual implementation and available commands as well as the expected target behavior is dependent on the debugger.
          The J-Link User Guide describes the common available Semihosting commands in general.

          For GDB Server SYS_RENAME and SYS_REMOVE are disabled for security reasons.
          You could otherwise, intended or not intended, severely mess up the debugger host.
          In the GDB Server you should have seen a message about this when you tried to execute those commands:
          “Semi hosting error: SYS_RENAME: Target tries to rename file. Declined for security reasons.”

          All other Semihosting commands are available and tested with GDB Server.”

          Have you some information about that ?

          Thanks

          Like

        • That’s new to me. But it makes sense that they do not allow rename and delete. But these functions are not used by the gcov library, so this does not really matter? Have you tried my test code?

          Liked by 1 person

  4. Pingback: FreeRTOS: how to End and Restart the Scheduler | MCU on Eclipse

  5. hi Erich,

    I was trying implement code coverage for one of example projects in frdm-k64 sdk (ver 2.5). I was able to generate the .gcno files , but I get a message in console that the .gcda creation is skipped.

    The print is “profiling:C:\Users\Documents\MCUXpressoIDE_10.3.1_2233\workspace_2\frdmk64f_hello_world\Debug/source/source_file.gcda:Skip”

    Like

  6. Pingback: Tutorial: GNU Coverage with MCUXpresso IDE | MCU on Eclipse

  7. Pingback: Tutorial: GNU gcov Coverage with the NXP i.MX RT1064 | MCU on Eclipse

What do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.