关于 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 访问系统,也许会有所帮助。
我是 运行 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 访问系统,也许会有所帮助。