36

我试图了解-pg(或-p)标志在编译 C 代码时是如何工作的gcc

官方 gcc 文档仅说明

-pg
生成额外的代码来编写适合分析程序 gprof 的配置文件信息。在编译需要数据的源文件时必须使用此选项,并且在链接时也必须使用它。

这真的让我很感兴趣,因为我正在对分析器进行一项小型研究——试图为这项工作选择最好的工具。

4

3 回答 3

30

使用仪器编译-pg您的代码以便gprof报告详细信息,请参阅gprof 的手册,9.1 分析的实现

分析通过改变程序中每个函数的编译方式来工作,以便在调用它时,它会隐藏一些关于它从哪里调用的信息。由此,分析器可以找出调用它的函数,并且可以计算它被调用了多少次。当您的程序使用该选项编译时,编译器会进行此更改-pg,这会导致每个函数调用mcount(或_mcount,或__mcount,取决于操作系统和编译器)作为其第一个操作之一。

包含在分析库中的mcount例程负责在内存调用图表中记录其父例程(子例程)及其父例程的父例程。这通常是通过检查堆栈帧来找到子地址和原始父节点的返回地址来完成的。由于这是一个非常依赖机器的操作,mcount它本身通常是一个简短的汇编语言存根例程,它提取所需的信息,然后__mcount_internal用两个参数调用(一个普通的 C 函数)——<code>frompc 和selfpc. __mcount_internal负责维护内存调用图,其中记录frompcselfpc和每个调用弧被遍历的次数。

...

请注意,使用这样的检测分析器,您正在分析您将在发布时编译的相同代码,而无需分析检测。有与检测代码本身相关的开销。此外,检测代码可能会改变指令和数据缓存的使用。

与检测分析器相反,像英特尔 VTune这样的采样分析器通过使用操作系统中断定期查看目标程序的程序计数器来处理非检测代码。它还可以查询特殊的 CPU 寄存器,让您更深入地了解正在发生的事情。

另请参见Profilers Instrumenting Vs Sampling

于 2011-09-03T00:04:37.923 回答
9

此链接简要说明了 gprof 的工作原理。

该链接对其进行了广泛的批评。(检查我对存档问题的回答。)

于 2011-09-03T16:13:26.447 回答
0

从这个来源:https://elinux.org/images/0/0c/Bird-LS-2009-Measuring-function-duration-with-ftrace.pdf

" 检测有两种主要形式 — 显式声明的跟踪点和隐式跟踪点。显式跟踪点由开发人员定义的声明组成,这些声明指定跟踪点的位置,以及有关应在特定跟踪站点收集哪些数据的附加信息。隐式跟踪点被放置由于编译器标志或开发人员对常用宏的重新定义,编译器会自动进入代码。

为了隐式检测函数,当内核配置为支持函数跟踪时,内核构建系统将 -pg 添加到编译器使用的标志中。这会导致编译器将代码添加到每个函数的序言中,这会调用一个名为 mcount 的特殊汇编例程。此编译器选项专门用于分析和跟踪目的。"

于 2017-09-15T01:24:24.357 回答