关于 Linux 内核中的 gcov 输出?

Regarding gcov output in Linux kernel?

我是 运行 gcov 在 Linux 内核树中,我得到了正确的报告,但打印在每个文件头的一些摘要不正确,如下所示:-

    -:    0:Graph:page_alloc.gcno
    -:    0:Data:page_alloc.gcda
    -:    0:Runs:0
    -:    0:Programs:0

在这里我们可以看到运行次数和程序运行次数都为零,这是不正确的。这个错误可能是什么原因?

从这里开始:

https://www.kernel.org/doc/Documentation/gcov.txt

您是否能够在您的系统中看到以下所有文件(在 /sys/kernel/debug 上安装了 debugfs):

/sys/kernel/debug/gcov
/sys/kernel/debug/gcov/reset
/sys/kernel/debug/gcov/path/to/compile/dir/file.gcda
/sys/kernel/debug/gcov/path/to/compile/dir/file.gcno

“/path/to/compile/dir”取决于您的内核文件。

Ans 然后你应用 gcov 命令:

# cd /tmp/linux-out
# gcov -o /sys/kernel/debug/gcov/tmp/linux-out/kernel spinlock.c

而且 bugzilla.kernel.org gcov 似乎没有任何错误,除了一个错误。

https://bugzilla.kernel.org/show_bug.cgi?id=57621

很可能是您的设置错误或命令行问题。

关于从 /sys/kernel/debug 读取的另一件事:这些是读取内核内部计数器的接口。如果您没有在用户空间级别执行任何操作,这将导致触发您对分析感兴趣的内核函数,那么输出将始终保持为零。因此,继续在用户空间中做尽可能多的活动(例如,如果您对文件系统 API 或 "ps -ef" 或 [=55 感兴趣,则 "ls -alR /" 从 root 开始进行递归读取=] 如果你对 procfs 感兴趣,或者如果你想分析网络 APIs.)"wget/ping" 命令。)

针对您的追踪案例"page_alloc",建议发出以下命令:

zip -r /tmp/my.zip /home/xxx

这有望触发使用动态内存读取 /home/xxx 中的文件,然后将其压缩。压缩算法通常需要您分配足够的内存来包含所有数据,然后才能开始压缩。 (这与加密算法形成对比,加密算法可能只需要一个固定的内存块来完成所有加密,因此不会出现很多 "page_alloc" 内核调用)。

就我而言,我只关注一个文件:kernel/sched/core.c:

gcov -o /sys/kernel/debug/gcov/home/tthtlc/linux_latest/kernel/sched core.c

然后用 vi 查看文件 core.c.gcov:

  2396808:   98:void update_rq_clock(struct rq *rq)
        -:   99:{
        -:  100:    s64 delta;
        -:  101:
        -:  102:    lockdep_assert_held(&rq->lock);
        -:  103:
  2396808:  104:    if (rq->clock_skip_update & RQCF_ACT_SKIP)
        -:  105:        return;
        -:  106:
  1676266:  107:    delta = sched_clock_cpu(cpu_of(rq)) - rq->clock;
  1677622:  108:    if (delta < 0)
        -:  109:        return;
  1677556:  110:    rq->clock += delta;
        -:  111:    update_rq_clock_task(rq, delta);
        -:  112:}

所以你可以看到它被执行了很多次。

并为 _alloc 执行 grep:

core.c.gcov:        -: 5325:static struct ctl_table *sd_alloc_ctl_entry(int n)
core.c.gcov:       16: 5376:sd_alloc_ctl_domain_table(struct sched_domain *sd)
core.c.gcov:        -: 5378:    struct ctl_table *table = sd_alloc_ctl_entry(14);
core.c.gcov:        8: 5416:static struct ctl_table *sd_alloc_ctl_cpu_table(int cpu)
core.c.gcov:        8: 5425:    entry = table = sd_alloc_ctl_entry(domain_num + 1);
core.c.gcov:       16: 5434:        entry->child = sd_alloc_ctl_domain_table(sd);
core.c.gcov:        1: 5445:    struct ctl_table *entry = sd_alloc_ctl_entry(cpu_num + 1);
core.c.gcov:        8: 5458:        entry->child = sd_alloc_ctl_cpu_table(i);
core.c.gcov:        -: 6086:enum s_alloc {
core.c.gcov:       28: 6217:        atomic_set(&(*sg)->sgc->ref, 1); /* for claim_allocations */
core.c.gcov:        -: 6346:static int __sdt_alloc(const struct cpumask *cpu_map);
core.c.gcov:        1: 6348:static void __free_domain_allocs(struct s_data *d, enum s_alloc what,
core.c.gcov:        1: 6364:static enum s_alloc __visit_domain_allocation_hell(struct s_data *d,
core.c.gcov:        1: 6369:    if (__sdt_alloc(cpu_map))
core.c.gcov:        -: 6382: * sched_group structure so that the subsequent __free_domain_allocs()
core.c.gcov:       16: 6385:static void claim_allocations(int cpu, struct sched_domain *sd)
core.c.gcov:        1: 6845:static int __sdt_alloc(const struct cpumask *cpu_map)
core.c.gcov:        -: 6971:    enum s_alloc alloc_state;
core.c.gcov:        1: 6976:    alloc_state = __visit_domain_allocation_hell(&d, cpu_map);
core.c.gcov:       16: 7016:            claim_allocations(i, sd);
core.c.gcov:        1: 7031:    __free_domain_allocs(&d, alloc_state, cpu_map);
core.c.gcov:        4: 8198:cpu_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
core.c.gcov:        -: 8595:    .css_alloc  = cpu_cgroup_css_alloc,

如果您能详细说明您的详细设置并使用 gcov 访问系统,也许会有所帮助。