perf 如何采样内核堆栈?

Posted

技术标签:

【中文标题】perf 如何采样内核堆栈?【英文标题】:How does perf sample kernel stacks? 【发布时间】:2019-01-30 14:52:15 【问题描述】:

据我所知 perf 能够为每个进程/线程采样一个完整的调用堆栈,即使它当前位于内核内部。由于我假设 perf 在用户空间中运行,我想知道它如何访问不同进程/线程的堆栈的内核部分。

目的是编写一个应用程序,可以对其他进程/线程的调用堆栈进行采样,即使它们当前位于内核中。

问候

【问题讨论】:

【参考方案1】:

perf 由两部分组成。用户空间工具和perf_event_open 系统调用。

通常,堆栈采样是由内核通过系统调用完成的。您可以编写一个应用程序同时使用 perf_event_open - 默认情况下包括内核示例 (exclude_kernel==0)。

【讨论】:

根据手册,我必须设置一个 perf_event_attr 结构的参数,然后用 perf_event_open 打开一个文件描述符,然后通过 read 继续读取它。假设我的目标是获取挂起进程的调用堆栈,我应该订阅哪些事件类型以及我将如何解析读取的数据? 可以阅读也可以mmap。要获取调用堆栈,您可以设置类似attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU | PERF_SAMPLE_CALLCHAIN 的内容。例如,您可以使用PERF_TYPE_HARDWARE // PERF_COUNT_HW_CPU_CYCLES PERF_COUNT_HW_CPU_CYCLES 会产生多少个事件?每次 CPU 做什么?对进程调度事件进行采样会更便宜吗? 录制速率由attr.sample_periodattr.sample_freqattr.freq 相应设置决定。手册页包含所有详细信息。 注意:这是一项相当复杂的工作,我无法在答案中提供完整的教程,但我很乐意回答更多具体问题。

以上是关于perf 如何采样内核堆栈?的主要内容,如果未能解决你的问题,请参考以下文章

内核调试-perf introduction

perf界面乱码

perf 命令

perf命令

Linux中CPU性能分析工具perf简单使用(亲测可用)

如何使用perf捕获组合的内核和用户空间堆栈