问题 从perf获取用户空间堆栈信息


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

我以为是Linux的 perf 工具对此非常理想,但我很难捕获块I / O性能计数器指标并将它们与用户空间活动相关联。

记录块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 它会拍摄快照 核心 堆栈,但不捕获内核中捕获的perf事件的用户空间状态。用户空间堆栈仅从用户空间上升到入口点,如 LWLockReleaseLWLockAcquirememcpy (mmap'd IO), __GI___libc_write

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

我在Fedora 19,3.11.3-201.fc19.x86_64,Schrödinger的Cat,使用perf版本3.10.9-200.fc19.x86_64。


9935
2017-11-01 02:30


起源

回到这一点,另一种可能是使用frace / systemtap / uprobes / ...而不是。在linux.conf.au 2014上的一次演讲表明,systemtap可以在这一点上更容易地做到这一点。 - Craig Ringer


答案:


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

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

  • ....除非它是一个新的版本 libunwind 支持,在这种情况下它支持 perf record -g dwarf

看到:

我在Fedora 18上,但是 同样的问题也适用。因此,如果您正在分析您正在处理的代码(可能在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
  • make

...我做了并测试了更新的 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 --with perf kernel.spec 生产新的 perf 没有构建整个内核的RPM。或者如果你想,省略 --without 对于你想要的内核风格,在这种情况下你还需要构建头文件,debuginfo等。

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

看到 关于构建自定义内核的fedora项目指南

我已经向Fedora报告了这个问题;他们不应该使用 NO_LIBUNWIND=1。看到 错误1025603

一旦你重建了 perf 您可以使用 perf record -g dwarf获得完整的堆栈。


15
2017-11-01 03:44



非常彻底和启发! - Erwin Brandstetter
@ErwinBrandstetter你可能会喜欢后续的博客文章: blog.2ndquadrant.com/tracing-postgresql-perf - Craig Ringer