我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记录的单独时间戳记日志中合并此信息?
答案 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