2

现在已经能够perf捕获用户空间堆栈,但我不确定如何说服它捕获通过引用传递的值作为指针,或捕获感兴趣的全局快照。

具体来说,我正在尝试分析 PostgreSQL 在各种负载下的系统范围性能,无论是否有性能相关的补丁。我需要做的关键事情之一是告诉内核中哪些查询哪些块 I/O 请求相关联。

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

这似乎是您期望它能够做的事情,因为通常单独的堆栈并不能告诉您正在发生的事情,如果它已经可以读取符号表,它应该能够查看up globals 并知道哪些函数参数是需要取消引用的指针并复制前“n”个字节。

不过,我一生都无法弄清楚如何做到这一点,或者这是否可能。我只是运气不好?我需要破解perf injectPostgreSQL 记录的单独时间戳日志中的这些信息吗?

4

2 回答 2

4

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

perf探针可以接受参数,这些参数可以是虚拟类$retval、寄存器类%axc 标识符以及局部或全局变量的简单表达式。

因此,如果perf确实支持参数的用户空间符号探针,您将创建一个探针来捕获调用的query_string参数,exec_simple_query例如:

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

于 2013-11-06T08:05:13.520 回答
1

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

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

于 2015-07-07T09:33:49.263 回答