我正在尝试理解使用GCC编译C代码时,-pg
(或-p
)标志的工作原理。
官方的GCC文档仅说明:
-pg
生成额外的代码以编写适用于分析程序gprof的配置文件信息。您必须在编译要获取数据的源文件时使用此选项,并且在链接时也必须使用它。
这真的很有趣,因为我正在进行关于分析器的小型研究。我正在尝试选择最适合该工作的工具。
我正在尝试理解使用GCC编译C代码时,-pg
(或-p
)标志的工作原理。
官方的GCC文档仅说明:
-pg
生成额外的代码以编写适用于分析程序gprof的配置文件信息。您必须在编译要获取数据的源文件时使用此选项,并且在链接时也必须使用它。
这真的很有趣,因为我正在进行关于分析器的小型研究。我正在尝试选择最适合该工作的工具。
使用 -pg 编译选项可以对您的代码进行仪器化处理,这样 Gprof 就可以提供详细信息报告。请参见 gprof 的手册,第 9.1 节:分析实现:
分析是通过更改程序中每个函数的编译方式来实现的,这样当它被调用时,就会存储有关其调用位置的一些信息。从这里,分析器可以确定是哪个函数调用了它,并计算它被调用的次数。编译程序时使用
-pg
选项进行此更改,这将导致每个函数作为其最初操作之一调用mcount
(或者根据操作系统和编译器的不同还可能是_mcount
或__mcount
)。分析库中包含的
mcount
子程序负责将其父子例程(即子例程和其父例程)记录在内存中的调用图表中。通常,这是通过检查堆栈帧来找到子程序的地址和原始父程序中的返回地址来完成的。由于这是一个非常依赖于机器的操作,因此mcount
本身通常是一个短汇编语言存根子程序,它提取所需的信息,然后使用两个参数 -frompc
和selfpc
调用__mcount_internal
(一个普通的C函数)。__mcount_internal
负责维护内存中的调用图表,记录每个调用弧的frompc
、selfpc
和被遍历的次数。...
请注意,使用这种仪器化分析器进行分析时,您正在分析与无分析仪器相同的代码。仪器化代码本身会带来额外的开销。此外,仪器化代码可能会改变指令和数据缓存的使用情况。
与工具化的分析器不同,像Intel VTune这样的采样分析器通过使用操作系统中断定期检查目标程序计数器来处理未被工具化的代码。它还可以查询特殊的CPU寄存器,以便更深入地了解正在发生的情况。
此外,参见分析器工具化 Vs 采样。
来自"使用Ftrace测量函数持续时间":
仪器分为两种主要形式——显式声明的跟踪点和隐式跟踪点。
显式跟踪点由开发人员定义的声明组成,它们指定跟踪点的位置以及关于在特定跟踪站点收集哪些数据的其他信息。隐式跟踪点是由编译器自动放置到代码中的,这要么是由于编译器标志,要么是由于开发人员重新定义常用宏。
要隐式地检测函数,当内核配置为支持函数跟踪时,内核构建系统会将-pg添加到与编译器一起使用的标志中。这会导致编译器向每个函数的序言添加代码,调用一个名为mcount的特殊汇编例程。此编译器选项专门用于性能分析和跟踪目的。