“perf”事件中的空间变量
我现在已经能够获得perf
来捕获用户空间栈了,但我不确定如何说服它捕获通过引用传递的值作为指针,或者捕获感兴趣的全局快照。
具体来说,我试图分析PostgreSQL在各种负载下的系统级性能,有无性能相关补丁。 我需要做的关键事情之一是告诉哪些查询与内核中的哪些块I / O请求相关联。
perf
记录了pid和用户空间堆栈,它们有时包含current_query
,但由于它是一个字符串,因此它被传入,所以我得到的只是一个不透明的指针。 不是很有用。 它不会出现在所有的痕迹,要么,所以最好我捞出全球PostgreSQL的存储在的价值,并得到perf
记录与每个跟踪样本。 事实之后将pid匹配到查询可能是可行的,但给定的PostgreSQL后端(pid)在其生命周期中不会运行一个查询,因此需要在perf
踪迹和PostgreSQL日志之间有很多相关的时间戳。
这看起来就像你期望能够做到的那种事情,因为单独一个堆栈往往不会告诉你所发生的事情,以及它是否已经可以读取它应该能够看到的符号表了解全局变量并知道哪些函数参数是需要被去引用的指针以及复制的第一个“n”个字节。
但是我不能为了我的生活找出如何去做,或者如果这是可能的,但是。 我只是运气不好? 我是否需要破解perf inject
来合并PostgreSQL记录的单独时间戳日志中的这些信息?
事实证明, perf
已经具有perf probe
所需的功能,但目前仅适用于内核空间。
perf
探针可以接受参数,这些参数可能像$retval
那样是虚拟的,像%ax
这样的寄存器,或者是本地或全局变量的c标识符和简单表达式。
所以,如果perf
确实支持用户空间的象征探针参数,你会创建一个探头捕获query_string
参数exec_simple_query
调用与类似:
perf probe -x /path/to/postgres exec_simple_query debug_query_string:string
该:string
告诉perf
它是一个C字符串,所以它应该deref指针并复制数据。
有多个地方可以进行查询 - 简单协议,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
,除非你热衷于自己增强工具。 好吧。
Fedora 22上的Perf支持用户空间探测器:
# perf --version; uname -r perf version 4.0.6-300.fc22.x86_64 4.0.4-301.fc22.x86_64