gcov kernel support
Subsystems (4)
cover gcov kernel support
This is version #2 of the gcov kernel support patch set (see further below for an in-depth explanation). Patch base is 2.6.26-rc3.
Changes are mostly based on mailing list feedback:
* added more documentation
* moved gcov config menu to general setup
* renamed some structures and variables (removed _t, lowercase ctors)
* split mod versioning change into separate patch (3)
* split GCC_VERSION_LOWER into separate patch (2)
* split gcov core patch into two patches (5+6) for better readability
* absolute paths only used when CONFIG_GCOV_PROFILE is set
* fixed compile problem with CONFIG_MODULES=n
* fixed memory leak in gcov fs code
* more style changes
Patch overview:
[PATCH 1/7] kernel: call constructors
[PATCH 2/7] kernel: introduce GCC_VERSION_LOWER macro
[PATCH 3/7] kbuild: delay object file renaming during module versioning [PATCH 4/7] seq_file: add function to write binary data [PATCH 5/7] gcov: add gcov profiling infrastructure
[PATCH 6/7] kbuild: make source and include paths absolute [PATCH 7/7] gcov: architecture specific compile flag adjustments
===
This set of patches enables the use of GCC's coverage testing tool gcov [1] with kernel 2.6.25. Coverage data for the running kernel is exported via debugfs in a gcov-compatible format. To get coverage data for a specific file, simply use gcov with the -o option:
# gcov -o /sys/kernel/debug/gcov/tmp/linux-2.6.25/kernel spinlock.c
This will create source code files annotated with execution counts in the current directory. In addition, graphical gcov front-ends such as lcov [2] can be used to automate the process of collecting data for the entire kernel and provide coverage overviews in HTML format.
Possible uses:
* debugging (has this line been executed at all?)
* test improvement (how do I change my test to cover these lines?)
* minimizing kernel configurations (do I need this option if the associated code is never executed?)
Known issues:
* some architecture specific problems: the patch has been tested successfully on s390 and i386. Known problems exist on x86_64 and arm (to be investigated)
* GCC's profiling mechanism together with optimization sometimes produces skewed data (see [1])
* GCC's profiling code assumes single-threaded execution
* gcov assumes that a program has finished when coverage data is analyzed
Despite these issues, the data which can be obtained has been proven to be sufficiently accurate for most practical uses.
History:
Hubertus Franke <[email protected]> wrote the first version of this patch around 2002. Since then it has been adapted to new versions of the kernel and GCC with contributions by several people (see file kernel/gcov/fs.c, write me if I missed anyone). Due to regular requests, I rewrote the gcov-kernel patch from scratch so that it would (hopefully) be fit for inclusion into the upstream kernel.
--
[1] http://gcc.gnu.org/onlinedocs/gcc/Gcov.html
[2] http://ltp.sourceforge.net/coverage/lcov.php
Quoted 2 lines · Peter Oberparleiter
This is version #2 of the gcov kernel support patch set (see further below for an in-depth explanation). Patch base is 2.6.26-rc3.
I reviewed the patches and they look good to me (except for some minor nits, probably not worth fixing)
-Andi
Quoted 1 line · On Mon, 19 May 2008 10:42:54 +0200 Peter Oberparleiter…
This is version #2 of the gcov kernel support patch set
powerpc blew up:
/opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/lib/gcc/powerpc64-unknown-linux-gnu/4.1.0/../../../../powerpc64-unknown-linux-gnu/bin/ld: skipping incompatible /opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/lib/gcc/powerpc64-unknown-linux-gnu/4.1.0/./libgcov.a when searching for -lgcov /opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/lib/gcc/powerpc64-unknown-linux-gnu/4.1.0/../../../../powerpc64-unknown-linux-gnu/bin/ld: cannot find -lgcov
collect2: ld returned 1 exit status
make[2]: *** [arch/powerpc/kernel/vdso32/vdso32.so.dbg] Error 1
make[1]: *** [arch/powerpc/kernel/vdso32] Error 2
Quoted 10 lines
Quoted 1 line
This is version #2 of the gcov kernel support patch set
powerpc blew up:
/opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/lib/gcc/powerpc64-unknown-linux-gnu/4.1.0/../../../../powerpc64-unknown-linux-gnu/bin/ld: skipping incompatible/opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/lib/gcc/powerpc64-unknown-linux-gnu/4.1.0/./libgcov.awhen searching for -lgcov/opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/lib/gcc/powerpc64-unknown-linux-gnu/4.1.0/../../../../powerpc64-unknown-linux-gnu/bin/ld: cannot find -lgcov
collect2: ld returned 1 exit status
make[2]: *** [arch/powerpc/kernel/vdso32/vdso32.so.dbg] Error 1
make[1]: *** [arch/powerpc/kernel/vdso32] Error 2
Sounds like your toolchain was built without biarch support, but you're using it for the 32-bit parts of the kernel anyway. Which works as long as you're not using any libraries, but now you need libgcov.a .
What does
/opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/bin/powerpc64-unknown-linux-gnu-gcc -v
say? (Or whatever the correct path to that compiler is, the directory structure is a bit unusual here it seems). There shouldn't be a --disable-biarch there.
Or, what does
find /opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/4.1.0/ -name libgcov.a
say? (It should usually find three versions: 64-bit, 32-bit, 32-bit no float).
You *can* build with a non-biarch compiler, but then you need to point the kernel build system at a 32-bit toolchain to use for the 32-bit parts (via CROSS32_COMPILE).
Segher
Quoted 17 lines · On Fri, 23 May 2008 13:06:00 +0200 Segher Boessenkool…
Quoted 4 lines
Quoted 1 line
This is version #2 of the gcov kernel support patch set
powerpc blew up:
Quoted 12 lines
/opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/lib/gcc/powerpc64-unknown-linux-gnu/4.1.0/../../../../powerpc64-unknown- linux-gnu/bin/ld: skipping incompatible/opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/lib/gcc/powerpc64-unknown-linux-gnu/4.1.0/./libgcov.a when searching for -lgcov/opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/lib/gcc/powerpc64-unknown-linux-gnu/4.1.0/../../../../powerpc64-unknown- linux-gnu/bin/ld: cannot find -lgcov
collect2: ld returned 1 exit status
make[2]: *** [arch/powerpc/kernel/vdso32/vdso32.so.dbg] Error 1 make[1]: *** [arch/powerpc/kernel/vdso32] Error 2
Quoted 3 lines
Sounds like your toolchain was built without biarch support, but you're using it for the 32-bit parts of the kernel anyway. Which works as long as you're not using any libraries, but now you need libgcov.a .
ok..
Quoted 6 lines
What does
/opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/bin/powerpc64-unknown-linux-gnu-gcc -vsay?
y:/home/akpm> /opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/bin/powerpc64-unknown-linux-gnu-gcc -v
Using built-in specs.
Target: powerpc64-unknown-linux-gnu
Configured with: /home/axboe/crosstool-0.43/build/powerpc64-unknown-linux-gnu/gcc-4.1.0-glibc-2.3.6/gcc-4.1.0/configure --target=powerpc64-unknown-linux-gnu --host=x86_64-host_unknown-linux-gnu --prefix=/opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu --disable-multilib --with-sysroot=/opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/powerpc64-unknown-linux-gnu/sys-root --with-local-prefix=/opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/powerpc64-unknown-linux-gnu/sys-root --disable-nls --enable-threads=posix --enable-symvers=gnu --enable-__cxa_atexit --enable-languages=c --enable-shared --enable-c99 --enable-long-long Thread model: posix
gcc version 4.1.0
Quoted 4 lines
(Or whatever the correct path to that compiler is, the directory
structure is a bit unusual here it seems). There shouldn't be a --disable-biarch there.
Quoted 8 lines
Or, what does
find
/opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/4.1.0/-name libgcov.asay? (It should usually find three versions: 64-bit, 32-bit, 32-bit no float).
Only a single hit:
/opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/lib/gcc/powerpc64-unknown-linux-gnu/4.1.0/libgcov.a
and it contains
y:/home/akpm/ppc> ar x libgcov.a y:/home/akpm/ppc> l
total 316
-rw-r--r-- 1 akpm akpm 44192 May 23 09:53 _gcov.o
-rw-r--r-- 1 akpm akpm 8448 May 23 09:53 _gcov_execl.o -rw-r--r-- 1 akpm akpm 8584 May 23 09:53 _gcov_execle.o -rw-r--r-- 1 akpm akpm 8456 May 23 09:53 _gcov_execlp.o -rw-r--r-- 1 akpm akpm 7384 May 23 09:53 _gcov_execv.o -rw-r--r-- 1 akpm akpm 7544 May 23 09:53 _gcov_execve.o -rw-r--r-- 1 akpm akpm 7392 May 23 09:53 _gcov_execvp.o -rw-r--r-- 1 akpm akpm 7264 May 23 09:53 _gcov_fork.o -rw-r--r-- 1 akpm akpm 7240 May 23 09:53 _gcov_interval_profiler.o -rw-r--r-- 1 akpm akpm 7464 May 23 09:53 _gcov_merge_add.o -rw-r--r-- 1 akpm akpm 8544 May 23 09:53 _gcov_merge_delta.o -rw-r--r-- 1 akpm akpm 8488 May 23 09:53 _gcov_merge_single.o -rw-r--r-- 1 akpm akpm 6976 May 23 09:53 _gcov_one_value_profiler.o -rw-r--r-- 1 akpm akpm 6856 May 23 09:53 _gcov_pow2_profiler.o
-rw-r--r-- 1 akpm akpm 146492 May 23 09:52 libgcov.a
y:/home/akpm/ppc> file _gcov_merge_delta.o
_gcov_merge_delta.o: ELF 64-bit MSB relocatable, 64-bit PowerPC or cisco 7500, version 1 (SYSV), not stripped
Quoted 4 lines
You *can* build with a non-biarch compiler, but then you need to point the kernel build system at a 32-bit toolchain to use for the 32-bit parts (via
CROSS32_COMPILE).
Jens built this one, using crosstool. It is
http://userweb.kernel.org/~akpm/cross-compilers/power64-cross.tar.bz2
It was all working happily until gcov came along :(
Quoted 23 lines
Quoted 3 lines
Sounds like your toolchain was built without biarch support, but you're using it for the 32-bit parts of the kernel anyway. Which works as long as you're not using any libraries, but now you need libgcov.a .
ok..
Quoted 6 lines
What does
/opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/bin/powerpc64-unknown-linux-gnu-gcc -vsay?
y:/home/akpm>
/opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/bin/powerpc64-unknown-linux-gnu-gcc-v Using built-in specs.
Target: powerpc64-unknown-linux-gnu
Configured with:/home/axboe/crosstool-0.43/build/powerpc64-unknown-linux-gnu/gcc-4.1.0-glibc-2.3.6/gcc-4.1.0/configure
--target=powerpc64-unknown-linux-gnu
--host=x86_64-host_unknown-linux-gnu --prefix=/opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-
gnu
Quoted 1 line
--disable-multilib
That's the culprit. I believe 4.1.0 enables multilib by default on PowerPC compilers that target 64-bit by default (the patch for that is dated almost a full year before the 4.1.0 release). I have no idea why crosstool disables this support; perhaps there were some problems with some older GCC version (or this one, even; it's ancient as well).
Quoted 10 lines
Quoted 8 lines
Or, what does
find
/opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/4.1.0/-name libgcov.asay? (It should usually find three versions: 64-bit, 32-bit, 32-bit no float).
Only a single hit:
Right, as expected.
Quoted 8 lines
Quoted 3 lines
You *can* build with a non-biarch compiler, but then you need to point the kernel build system at a 32-bit toolchain to use for the 32-bit parts (via
CROSS32_COMPILE).Jens built this one, using crosstool. It is
http://userweb.kernel.org/~akpm/cross-compilers/power64-cross.tar.bz2It was all working happily until gcov came along :(
You were lucky, yes. If your compiler would have been just a little bit older it wouldn't have been able to build 32-bit at all.
Do you have a separate 32-bit PowerPC compiler? If so, just set CROSS32_COMPILE to it; if not, you'll need a new toolchain. In that case, it's probably worthwhile to upgrade to 4.1.2 at least...
Segher
Quoted 7 lines · On Fri, 23 May 2008 23:52:43 +0200 Segher Boessenkool…
Quoted 7 lines
Quoted 3 lines
You *can* build with a non-biarch compiler, but then you need to point the kernel build system at a 32-bit toolchain to use for the 32-bit parts (via
CROSS32_COMPILE).Jens built this one, using crosstool. It is
http://userweb.kernel.org/~akpm/cross-compilers/power64-cross.tar.bz2
Quoted 6 lines
Quoted 1 line
It was all working happily until gcov came along :(
You were lucky, yes. If your compiler would have been just a little bit older it wouldn't have been able to build 32-bit at all.
Do you have a separate 32-bit PowerPC compiler?
I dont' cross-compile for 32-bit power. This is all 64-bit stuff.
Quoted 3 lines
If so, just set
CROSS32_COMPILEto it; if not, you'll need a new toolchain. In that case, it's probably worthwhile to upgrade to 4.1.2 at least...
Sigh. Life's too short. I'll go back to testing powerpc builds on the powerpc box.
Quoted 11 lines · Andrew Morton
Quoted 1 line · On Mon, 19 May 2008 10:42:54 +0200 Peter Oberparleiter…
This is version #2 of the gcov kernel support patch set
powerpc blew up:
/opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/lib/gcc/powerpc64-unknown-linux-gnu/4.1.0/../../../../powerpc64-unknown-linux-gnu/bin/ld: skipping incompatible/opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/lib/gcc/powerpc64-unknown-linux-gnu/4.1.0/./libgcov.awhen searching for -lgcov/opt/crosstool/gcc-4.1.0-glibc-2.3.6/powerpc64-unknown-linux-gnu/lib/gcc/powerpc64-unknown-linux-gnu/4.1.0/../../../../powerpc64-unknown-linux-gnu/bin/ld: cannot find -lgcov
collect2: ld returned 1 exit status
make[2]: *** [arch/powerpc/kernel/vdso32/vdso32.so.dbg] Error 1
make[1]: *** [arch/powerpc/kernel/vdso32] Error 2
This looks like a secondary linking process. It's best to exclude the whole directory from GCOV profiling (which should ony work for C files anyway).
Below is an update for patch #7 of the gcov series that includes the corresponding changes.
---
[PATCH 7/7] gcov: architecture specific compile flag adjustments
From: Peter Oberparleiter <[email protected]>
Exclude code from profiling which is not linked to the main kernel or which is running in a context not compatible with the assumptions made by gcc's profiling code.
--- arch/arm/boot/compressed/Makefile | 1 + arch/powerpc/kernel/vdso32/Makefile | 1 + arch/powerpc/kernel/vdso64/Makefile | 1 + arch/ppc/boot/Makefile | 1 + arch/ppc/boot/common/Makefile | 1 + arch/ppc/boot/simple/Makefile | 1 + arch/x86/boot/Makefile | 1 + arch/x86/boot/compressed/Makefile | 1 + arch/x86/kernel/acpi/realmode/Makefile | 1 + 9 files changed, 9 insertions(+)
arch/arm/boot/compressed/Makefile +1 -0
@@ -7,6 +7,7 @@ HEAD = head.o OBJS = misc.o FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c +GCOV := n # # Architecture dependencies
arch/x86/boot/compressed/Makefile +1 -0
@@ -12,6 +12,7 @@ cflags-$(CONFIG_X86_64) := -mcmodel=smal KBUILD_CFLAGS += $(cflags-y) KBUILD_CFLAGS += $(call cc-option,-ffreestanding) KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector) +GCOV := n KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
arch/ppc/boot/Makefile +1 -0
@@ -16,6 +16,7 @@ # KBUILD_CFLAGS used when building rest of boot (takes effect recursively) KBUILD_CFLAGS += -fno-builtin -D__BOOTER__ -Iarch/$(ARCH)/boot/include HOSTCFLAGS += -Iarch/$(ARCH)/boot/include +GCOV := n BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd
arch/ppc/boot/common/Makefile +1 -0
@@ -5,6 +5,7 @@ # Tom Rini January 2001 # +GCOV := n lib-y := string.o util.o misc-common.o \ serial_stub.o bootinfo.o lib-$(CONFIG_SERIAL_8250_CONSOLE) += ns16550.o
arch/ppc/boot/simple/Makefile +1 -0
@@ -21,6 +21,7 @@ # XXX_memory.o file for this to work, as well as editing the # misc-$(CONFIG_MACHINE) variable. +GCOV := n boot := arch/ppc/boot common := $(boot)/common utils := $(boot)/utils
arch/x86/boot/Makefile +1 -0
@@ -71,6 +71,7 @@ KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os $(call cc-option, -mpreferred-stack-boundary=2) KBUILD_CFLAGS += $(call cc-option,-m32) KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ +GCOV := n $(obj)/zImage: IMAGE_OFFSET := 0x1000 $(obj)/zImage: asflags-y := $(SVGA_MODE) $(RAMDISK)
arch/x86/kernel/acpi/realmode/Makefile +1 -0
@@ -42,6 +42,7 @@ KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os $(call cc-option, -mpreferred-stack-boundary=2) KBUILD_CFLAGS += $(call cc-option, -m32) KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ +GCOV := n WAKEUP_OBJS = $(addprefix $(obj)/,$(wakeup-y))
arch/powerpc/kernel/vdso32/Makefile +1 -0
@@ -17,6 +17,7 @@ EXTRA_CFLAGS := -shared -fno-common -fno EXTRA_CFLAGS += -nostdlib -Wl,-soname=linux-vdso32.so.1 \ $(call ld-option, -Wl$(comma)--hash-style=sysv) EXTRA_AFLAGS := -D__VDSO32__ -s +GCOV := n obj-y += vdso32_wrapper.o extra-y += vdso32.lds
arch/powerpc/kernel/vdso64/Makefile +1 -0
@@ -11,6 +11,7 @@ EXTRA_CFLAGS := -shared -fno-common -fno EXTRA_CFLAGS += -nostdlib -Wl,-soname=linux-vdso64.so.1 \ $(call ld-option, -Wl$(comma)--hash-style=sysv) EXTRA_AFLAGS := -D__VDSO64__ -s +GCOV := n obj-y += vdso64_wrapper.o extra-y += vdso64.lds