如何使用 perf 收集一些可读的堆栈跟踪?

Posted

技术标签:

【中文标题】如何使用 perf 收集一些可读的堆栈跟踪?【英文标题】:How to collect some readable stack traces with perf? 【发布时间】:2018-03-17 20:16:31 【问题描述】:

我想在 Linux 上使用this answer 中描述的随机抽样来分析 C++ 程序:

但是,如果您赶时间并且可以手动中断您的 调试器下的程序虽然主观上很慢,但有 一种查找性能问题的简单方法。

问题是我不能使用 gdb 调试器,因为我想在重负载下对生产环境进行分析,而调试器的侵入性太强,会大大减慢程序的速度。但是我可以使用perf recordperf report 来查找瓶颈而不影响程序性能。有没有办法用 perf 而不是 gdb 收集许多可读的(类似 gdb 的)堆栈跟踪?

【问题讨论】:

IIRC,Chandler Carruth 在他的 CppCon2015 谈论 perf:youtube.com/watch?v=nXaxk27zwlk 中提到了启用帧指针的编译 (-fno-omit-frame-pointer) 以让 perf 有效地收集堆栈回溯。但我忘记了他使用什么性能选项告诉perf 它可以使用帧指针并让它甚至收集父调用者。这是一个非常好的视频,值得一看。 【参考方案1】:

perf 确实提供了三种不同技术的调用堆栈记录

默认使用帧指针 (fp)。这通常受支持并且性能良好,但不适用于某些优化。使用 -fno-omit-frame-pointer 等编译您的应用程序,以确保其正常运行。 dwarf 为每个样本使用麻袋转储进行后处理。这会导致显着的性能损失 现代系统可以使用硬件支持的最后一个分支记录lbr

堆栈可在perf 分析工具中访问,例如perf reportperf script

更多详情请查看man perf-record

【讨论】:

谢谢,你知道如何在perf script 的堆栈跟踪中添加行号吗?我试过perf script -F +srcline,但似乎他们没有被添加。是perf script 错误还是我做错了?

以上是关于如何使用 perf 收集一些可读的堆栈跟踪?的主要内容,如果未能解决你的问题,请参考以下文章

给定背景颜色,如何获得使其在该背景颜色上可读的前景色?

给定背景颜色,如何获得使其在背景颜色上可读的前景色?

如何收集功能模块执行的详细堆栈跟踪?

如何使用 kotlin.logging 记录堆栈跟踪?

如何在函数式编程映射方法中模拟“返回”语句(或其他使该代码工作和可读的方法)[关闭]

在 C# 中如何收集程序崩溃的堆栈跟踪