在“perf”事件中捕获用户空间变量

时间:2013-11-01 05:00:50

标签: c linux linux-kernel perf

now been able to get perf to capture a user-space stack`,但我不确定如何说服它捕获引用传递的值作为指针或感兴趣的快照全局。

具体来说,我试图在有和没有性能相关补丁的情况下分析各种负载下PostgreSQL的系统性能。我需要做的一件事是告诉哪些查询内核中的I / O请求阻塞

perf记录了pid和用户空间堆栈,它有时包含current_query,但由于它是一个字符串,它通过引用传递,所以我得到的是一个不透明的指针。不是很有用。它也没有出现在所有的痕迹中,所以理想情况下我会从全局PostgreSQL中存储它的值并让perf记录每个跟踪样本。事实上将pid与查询匹配可能是可行的,但是给定的PostgreSQL后端(pid)在其生命周期内不会只运行一个查询,因此需要在perf跟踪和PostgreSQL日志之间存在大量关联时间戳。

这看起来像是你希望它能够做的事情,因为通常只有一个堆栈并不能告诉你所发生的事情,如果它已经可以读取符号表那么它应该是能够查找全局变量并知道哪些函数参数是需要被解引用的指针并且复制了第一个'n'个字节。

我不能为我的生活弄清楚如何做到这一点,或者这是否可行。我运气不好吗?我是否需要破解perf inject从PostgreSQL记录的单独时间戳记日志中合并此信息?

2 个答案:

答案 0 :(得分:4)

事实证明perf已经具有perf probe所需的功能,但目前仅适用于内核空间。

perf探针可以使用参数,它可以是$retval之类的虚拟内容,%ax之类的寄存器,或 c标识符和简单表达式用于本地或全局变量。

因此,如果perf确实支持参数的用户空间符号探测,那么您将创建一个探测器以捕获query_string参数exec_simple_query被调用,例如:< / p>

perf probe -x /path/to/postgres exec_simple_query debug_query_string:string

:string告诉perf它是一个C字符串,所以它应该解析指针并复制数据。

查询可以有多个位置 - 简单协议,v3解析/绑定/执行协议,SPI等。这只是其中之一。您可以在raw_parse中从解析器捕获查询,或者从感兴趣的事件的探针中获取debug_query_string全局值。

不幸的是,这一切都不会起作用,因为perf不会对用户空间二进制文件进行符号查找:

$ sudo perf probe -x /path/to/postgres exec_simple_query debug_query_string:string
Debuginfo-analysis is not yet supported with -x/--exec option.
  Error: Failed to add events. (-38)
$ perf --version; uname -r
perf version 3.11.6
3.11.6-201.fc19.x86_64

所以 - 如果perf支持符号查找,你就可以通过查找结构成员来执行令人兴奋的事情,例如在执行程序中捕获查询文本:

perf probe -x `which postgres` standard_ExecutorStart 'queryDesc->sourceText:string'

...但是,perf还不知道如何进行所需的符号查找,并且它无法从寄存器和$retval中捕获C字符串。所以:等待一个新的perf,除非你热衷于自己增强工具。哦,好吧。

答案 1 :(得分:1)

Fedora 22上的Perf支持用户空间探测:

# perf --version; uname -r perf version 4.0.6-300.fc22.x86_64 4.0.4-301.fc22.x86_64