c - 从 perf 获取用户空间堆栈信息

标签 c linux linux-kernel perf

我目前正在尝试追踪我正在测试的 PostgreSQL 构建中的一些幻象 I/O。它是一个多进程服务器,将磁盘 I/O 关联回特定的后端和查询并不简单。

我认为 Linux 的 perf 工具将是这方面的理想选择,但我正在努力捕获 block I/O 性能计数器指标并将它们与用户空间事件相关联。

记录 block I/O 请求和完成很容易,例如:

sudo perf record -g -T -u postgres -e 'block:block_rq_*'

并且记录了用户空间 pid,但是没有捕获内核或用户空间堆栈,也没有对用户空间进程的堆(比如查询文本)等位进行快照的能力。所以当你有 pid 时,您不知道该过程当时在做什么。只是 perf script 输出如下:

postgres  7462 [002] 301125.113632: block:block_rq_issue: 8,0 W 0 () 208078848 + 1024 [postgres]

如果我将 -g 标志添加到 perf record 它将获取 kernel 堆栈的快照,但不会捕获用户- 内核中捕获的 perf 事件的空间状态。用户空间堆栈仅上升到用户空间的入口点,如 LWLockReleaseLWLockAcquirememcpy(mmap'd IO), __GI____libc_write

所以。有小费吗?能够捕获响应内核 事件的用户空间 堆栈的快照将是理想的。

我在 Fedora 19、3.11.3-201.fc19.x86_64、薛定谔的猫上,性能版本为 3.10.9-200.fc19.x86_64。

最佳答案

好的,看起来有几个部分:

  • 我在 x86_64 上,大多数发行版默认使用 -fomit-frame-pointer 构建,而 perf 无法在没有框架的情况下跟随堆栈指针;

  • .... 除非它是使用 libunwind 支持构建的较新版本,在这种情况下它支持 perf record -g dwarf

参见:

我在 Fedora 18 上,但是 the same issue applies .因此,如果您正在分析正在处理的代码(在 Stack Overflow 上很可能如此),请使用 -fno-omit-frame-pointer-ggdb 进行重建。

我着手重建 perf,因为我希望能够与库存 RPM 进行比较:

  • sudo yum build-dep perf
  • sudo yum install yum-utils rpmdevtools libunwind-devel
  • yumdownloader --source perf 或下载合适的kernel-.....src.rpm srpm
  • rpmdev-setuptree
  • rpm -Uvh kernel-*.src.rpm
  • cd $HOME/rpmbuild/SPECS
  • rpmbuild -bp --target=$(uname -m) kernel.spec

此时,如果需要,您可以构建一个新的 perf:

  • cd $HOME/rpmbuild/BUILD/kernel-*/linux-*/tools/perf
  • 制作

...我做了并测试了更新后的 perf 如果使用可用的 libunwind 构建,实际上确实捕获了一个有用的堆栈。

您还可以构建一个新的 rpm:

  • 编辑 kernel.spec,取消注释行 %define buildid ...,将 buildid 更改为类似 .perfunwind 的内容。请注意,它是 %define 而不是 %define

  • 在同一个 spec 文件中,找到:

    %global perf_make \
    make %{?_smp_mflags} -C tools/perf -s V=1 WERROR=0 NO_LIBUNWIND=1 HAVE_CPLUS_DEMANGLE=1 NO_GTK2=1 NO_LIBNUMA=1 NO_STRLCPY=1 prefix=%{_prefix}
    

    并删除 NO_LIBUNWIND=1

  • rpmbuild -bb --without up --without mp --without pae --without debug --without doc --without headers --without debuginfo --without bootwrapper --without with_vdso_install --使用 perf kernel.spec 生成新的 perf RPM 而无需构建整个内核。或者,如果您愿意,省略 --without 以获得您想要的内核风格,在这种情况下,您还需要构建 header 、调试信息等。

  • sudo rpm -Uvh $HOME/rpmbuild/RPMS/x86_64/perf-*.fc19.x86_64.rpm

参见 the fedora project guide on building a custom kernel .

我已经向 Fedora 报告了这个问题;他们不应该使用 NO_LIBUNWIND=1。参见 bug 1025603 .

重建perf 后,您可以使用perf record -g dwarf 获取完整堆栈。

关于c - 从 perf 获取用户空间堆栈信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19719911/

相关文章:

linux - vsftpd 的 html 代码在哪里/如何生成?

c - Windows平台下如何用C语言实现ping请求?

c - 将 64 位十六进制地址中的位提取到 C 中的无符号整数中

linux - scp作为后台工作?

Linux按日期排序 "ls -al"输出

linux - 在 Linux 中在内核和用户代码之间来回跳转

linux - 为什么映射值的物理地址始终为零?

c - 如何更改内核空间堆的权限?

c - Malloc 或普通数组定义?

c - scanf中的空格导致结果异常