GDB是否支持“运行时采样”,或者是否有用户“扩展”可以实现?

6
动机:我无法在代码运行的机器上使用谷歌CPU分析器(最后一口气中我诅咒libunwind :)),所以我想知道gdb是否支持程序执行的高频随机暂停,存储程序中断的函数名称,并计算它在函数x中暂停的次数。这就是我所说的“运行时抽样”,可能还有更精确/更智能的名称。 我看了oprofile,但它太复杂了,要么是a)弄清楚它是否能做到这一点,b)弄清楚如何做到这一点。 编辑:显然正确的名称是:“统计抽样方法”
编辑2:我为什么要为此提供赏金,因为我看到一些人在SO上建议手动中断10-20次并使用bt检查堆栈... 这似乎非常浪费时间,所以我猜测一些聪明的人已经自动化了它。 :)
编辑3:gprof行不通...我最近尝试在ARM系统上运行它,输出是垃圾... :( 我猜它在多线程方面存在问题...

手动采样如果你没有尝试过的话,似乎很浪费。请参见此处的第一个评论。此答案的最后一段。此答案此答案ErikE在此处的评论。此处的codelidoo评论。先试用一下,然后再弃用它。 - Mike Dunlavey
2个回答

3

GDB不能很好地做到这一点,尽管你可以肯定地编写一些东西来提供极不准确的结果。

我建议使用Valgrind的“Callgrind”插件。作为奖励,它绝对不需要重新编译或其他特殊设置。您所需要的只是在系统中安装了valgrind,并在程序中调试信息(或至少完整的符号信息;我不确定)。

然后,您可以像这样调用您的程序:

valgrind --tool=callgrind <your program command line>

完成后,当前目录中将有一个名为callgrind.out.<pid>的文件。您可以使用一个非常好的GUI工具称为kcachegrind(通常需要单独安装)来读取和可视化此文件。
唯一的问题是,由于callgrind会稍微减慢程序的执行速度,所以系统调用所花费的时间可能会比实际上更小(按百分比计算)。默认情况下,callgrind不包括系统时间在其计数器中,因此它给出的值是您程序中代码的真实比较,但不是该函数“下方”的实际时间。这可能会令人困惑,如果发生这种情况,请尝试添加--collect-systime=yes
我不确定ARM上callgrind的状态如何。 ARMv7被列为支持的平台,但只说“相当完整”,不知道这意味着什么。

我不确定Valgrind是否是一个选项,因为我没有编写这段代码,也不知道它是否依赖于某些超时...即如果从请求x开始200毫秒内x没有发生,则取消。 :) - NoSenseEtAl
它在x86_64上运行速度较慢,但仍然相当可观。我不能代表ARM发言。试一试,不需要太多的努力。 - ams
等等,Valgrind 不会减速 10+x 吗?而且我不能尝试它,因为目标硬件没有 Valgrind 或互联网连接。甚至没有 GCC。只有可爱的 GDB. :) - NoSenseEtAl
我认为Callgrind比Memcheck好一些,但我不确定。没有网络确实是一个棘手的问题。 :) - ams
顺便说一下,对于I/O事件的200ms超时仍然可以正常工作,因为这一切都在内核中运行,不受valgrind的影响。如果您有多个线程,则情况就不同了,而且很难进行分析。 - ams

3
您可以在运行时暂停GDB来手动采样。
您似乎认为您想要的是gprof,但是如果您的目标是使程序尽可能快,则建议:
- 高频率采样没有帮助。 - 计算程序计数器位于函数X中的采样次数除了在人工小型程序中没有用处。
如果您遵循该链接,您将看到原因以及成功执行的指示。

1
高频率采样而无需使用gprof标志进行编译将会很有帮助。 - rogerdpack
1
@rogerdpack:根据*这个链接*,我并不这么认为。也许需要花费足够的时间来修复某些问题,但是在10个样本中就能看到它们。其他990个样本并不能告诉你更多信息,反而会概括掉所有能够告诉你正在发生什么的洞察力。 - Mike Dunlavey
好的,我在你提供的链接中看到了一些其它可能有用的工具,比如lsstack、oprofile等。 非常感谢! 另外请注意看一下我的答案,其中列出了我所能找到的采样分析器:http://stackoverflow.com/a/11143125/32453 - rogerdpack

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接