gcc - Linux kernel 5.4 GCC 9.1.0 不显示代码覆盖率

标签 gcc linux-kernel x86-64 code-coverage gcov

我们在不同的架构(arm、arm64、x86_64)上使用 Linux 内核 5.4 和 gcc 9.1.0。我负责为内核模块创建代码覆盖率。我没有选择 Linux 内核版本或编译器版本。

我能够为 arm/arm64 创建代码覆盖率,并像往常一样在/sys/kernel/debugfs/gcov/... 中查看结果。此外,加载的模块在 gcov 子目录中可见。

但是,对于 x86_64,即使我设置了 CONFIG_GCOV_COVERAGE_ALL=y,我也只会看到/sys/kernel/debubfs/gcov/reset 而没有别的。

kernel/gcov/base.c 中的 __gcov_init 通常会创建一个

pr_info("version magic=...")

在启动时在 arm/arm64 上可见,但在 x86_64 上不可见。 __gcov_init 应该作为 gcc 构造函数为每个源文件调用,并且第一次调用会创建版本魔术消息。

在我看来,在我的组合中,代码覆盖函数 __gcov_init 从未在 x86_64 中被调用。

在配置中,我使用

CONFIG_GCOV_PROFILE=y
CONFIG_GCOV_FORMAT_4_7=y

有时仅适用于 x86 CONFIG_GCOV_PROFILE_ALL=y。对于 x86,除了“重置”文件之外没有任何内容可见/sys/kernel/debug/gcov/...。

欢迎提出任何建议。

最佳答案

代码覆盖构造函数现在写在“.ctors.65435”部分(数字可能是构造函数的优先级),但内核 5.4 只知道“.ctors”。

对于内核内部代码覆盖率,以下更改(已经在更高版本的内核中,例如 5.12)恢复了代码覆盖率

--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -631,6 +631,7 @@
 #ifdef CONFIG_CONSTRUCTORS
 #define KERNEL_CTORS() . = ALIGN(8);                      \
                        __ctors_start = .;                 \
+                       KEEP(*(SORT(.ctors.*)))            \
                        KEEP(*(.ctors))                    \
                        KEEP(*(SORT(.init_array.*)))       \
                        KEEP(*(.init_array))               \

然而,kernel/module.c 也不知道“.ctors.65435”,并且用 gcc9 或 gcc10 编译的模块没有“.ctors”ELF 部分。所以我只是改成了 HACK (!)

--- a/kernel/module.c
+++ b/kernel/module.c
@@ -3294,7 +3294,7 @@ static int find_module_sections(struct module *mod, struct load_info *info)
        mod->unused_gpl_crcs = section_addr(info, "__kcrctab_unused_gpl");
 #endif
 #ifdef CONFIG_CONSTRUCTORS
-       mod->ctors = section_objs(info, ".ctors",
+       mod->ctors = section_objs(info, ".ctors.65435",
                                  sizeof(*mod->ctors), &mod->num_ctors);
        if (!mod->ctors)
                mod->ctors = section_objs(info, ".init_array",

这带回了模块代码覆盖率,但是

模块的 .ctors.* 在最新的 5.x 内核中未知,所以我认为这应该在 Linux 内核模块处理中修复

关于gcc - Linux kernel 5.4 GCC 9.1.0 不显示代码覆盖率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67918686/

相关文章:

c++ - Eclipse CDT 控制台输出未显示在带有路径的调试中,也未显示在没有路径的运行中

c - GCC ASM 将 AH 寄存器从 C 设置为 1h

linux - 获取打开文件描述符的内存使用情况

android - 2019 年 8 月 NDK 64 位要求英特尔二进制文件

linux - 如何在 GAS 汇编中使用 "repne scasb"?

c - 如何清除 "warning: declaration does not declare anything [-fpermissive]"

c - 为什么在 Linux 编译器中编译和运行 C 程序时需要额外的参数?

linux-kernel - 如何复制结构文件?

c - 使用可加载内核模块的系统调用拦截中的参数似乎已损坏

linux - 如何多次返回被调用函数/NASM