Saturday, January 11, 2014

gcov run-time data format change - impact on gcov usage


In this post, I will cover gcov run time data formats & the impact of this on gcov usage.

gcov run-time data format change

The first time I tried getting code coverage for a kernel module, I didn't get any gcda files in /sys/kernel/debug/gcov. Only a reset file was present. When I debugged the issue, I found the root cause - an issue arising from gcov's run time data format change introduced in gcc 4.7. 

A new gcov run time data format is introduced in gcc 4.7. The new format has more efficient data structures used for profiling than the earlier format. 

Impact on gcov usage

Due to this format change, run time coverage information collection can be broken.

The application code instrumentation facility is provided by gcc's compile flags. The gcov run time data collection engine is provided by libcov in case of user space applications or additional kernel code in case of kernel modules.

To accommodate gcov run time format change, both gcc version as well as libgcov/kernel-gcov-code should be moved together. Otherwise, run time coverage information collection can be broken due to incompatibility between instrumented code & the gcov run time data collection engine.

  • Impact on User space Applications: As libgcov is part of gcc installation, we can safely assume that both gcc's instrumentation capability as well as gcov run time data collection engine are always moved together. So, one will not see any impact while using gcov on user space applications.
  • Impact on Kernel modules or Kernel: In case of kernel, kernel-gcov-code provides gcov run time data collection engine. The support for newer gcov run time format is added to kernel in 3.13 version. And the gcc version installed on the system is controlled by user. So, there is a significant possibility that gcc version & kernel-gcov-code become incompatible. Here are the possibilities:

   
Scenario1 : gcc version < 4.7, kernel-gcov-code < 3.11: compatible formats

Scenario 2: gcc version < 4.7, kernel-gcov-code > 3.11: incompatible, but linux kernel has backward compatibility for past gcc versions. Selet "Auto detect"..

Scenario 3 : gcc version >=4.7, kernel-gcov-code < 3.11: incompatible formats, run time data collection broken

Scenario 4: gcc version>=4.7, kernel version>3.11: compatible formats


I hit scenario 3. I solved it by upgrading my kernel to 3.13.5. Before recompiling 3.13.5 kernel, I selected "Autodetect Gcov format" in "make menuconfig". The exact steps are detailed in my other post at How to - Linux Kernel Compilation in Ubuntu VM/VirtualBox.

May be, gcc could have provided a facility to compile with earlier gcov formats. 

How to find your gcc version?

Refer my other post at  My cheatsheet for gcc


How to find your linux kernel version?

Refer "OS Info" section in my other post at Linux System Info Commands

Hope this helps.

1 comment:

Sachin said...

Hi,

I have system with GCC version >= 4.7 and kernel version>3.11. But still I could see only "reset" file under "/sys/kernel/debug/gcov" . Please do let me know what could be the issue or am I missing something here ? Thanks in advance.

[root@localhost gcov]# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC)
[root@localhost gcov]# uname -r
3.12.74

UA-48797665-1