【问题标题】:How can I make pprof show every single function in a call tree?如何让 pprof 显示调用树中的每个函数?
【发布时间】:2022-01-10 04:58:22
【问题描述】:

我正在尝试从https://github.com/greenplum-db/gpbackup 获取完整的 gpbackup 调用树。我使用 runtime/pprof,而不是 net/http/pprof,所以据我所知,收集统计信息不应该有任何时间限制。我在程序的最开始启动 pprof 服务器,并在 os.Exit() 命令之前停止它。为了收集统计信息,我运行 gpbackup,它按预期工作,我得到 cpu.prof 输出。然后我使用pprof --nodecount=100000 gpb cpu.prof 并使用png 命令生成一个调用树。问题是调用树缺少主要数量的功能。例如,DoBackup() 从记录函数开始,但它们在调用树中丢失了,而且还有许多其他函数似乎也没有出现。如何让 pprof 显示调用树中的每个调用?

【问题讨论】:

    标签: go pprof


    【解决方案1】:

    默认情况下,pprof removes nodes 的 CPU 时间少于 0.5%,边缘的 CPU 时间少于 0.1%。您可以通过提供 -nodefraction=0-edgefraction=0 标志来要求 pprof 不要这样做,这可能会解决您的问题。

    据我所知,收集统计数据不应该有任何时间限制

    不完全正确,runtime/pprof samples 100 times per second。每次采样时,它都会捕获完整的堆栈跟踪。因此,如果函数的执行速度超过 100 秒,并且不属于运行时间较长的函数的堆栈帧,那么您可能会错过函数。

    您可以复制 StartCPUProfile 并更改 hz 变量,以便更频繁地捕获。

    【讨论】:

    • 谢谢,它有助于显示一些调用,但树仍然没有所有调用的 1/10,尽管我尝试将刷新率设置为 400-500 Hz。实际上,我没有得到机制,因为我备份了同一个测试数据库,但每次我得到不同的分析结果
    • 分析时,我们请求操作系统以给定的时间间隔向进程发送中断。这是文档谈论的 SIGPROF 信号。当运行时收到此信号时,它会中断程序的执行并运行分析代码。此分析代码查看堆栈跟踪和中断时我们所处的位置。 pprof 然后计算它在特定函数中被中断的频率,这就是我们获得百分比的方式。因此,如果在函数中从未发生中断,则它永远不会出现在配置文件中。
    • 对不起,我没有正确表达我的问题。是的,我知道中断,但是如果函数运行时间不够长,为什么 pprof 会以这种方式丢失一些数据?例如,您必须以特定方式编译 c 程序,但无论执行时间如何,它都会被记录下来。所以,问题是为什么 pprof 可以为相同的命令和数据集提供不同的输出
    • pprof 的目标,一般分析是找出你的代码的哪一部分占用了最多的时间/内存,以便你可以改进它(优化)。因此,如果一个函数在整个配置文件的过程中花费的时间少于 100 秒,那么它只是为了找到占用 50% CPU 时间的函数而产生的噪音。第二个原因是这种方法可以在生产中使用,您不需要在代码中添加检测,即使您没有进行分析也会减慢您的速度。您只需在启用分析时付费。
    • 如果您对在哪些函数上花费了多少时间感兴趣,您应该使用trace 而不是 pprof。使用跟踪,您可以将用户注释添加到代码的特定时间部分。但这需要手动检测您的代码。
    猜你喜欢
    • 2022-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多