gcc的-pg选项

本文详细探讨了GCC编译器的-pg选项,该选项用于生成用于性能分析的gmon.out文件。通过使用-pg,开发者可以在运行程序后利用gprof等工具分析代码的性能瓶颈,优化程序执行效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



gcc的-pg选项
ftrace 支持动态trace,即可以跟踪内核和模块中任意的全局函数。它利用了gcc的-pg编译选项,在每个函数的开始增加一个stub,这样在需要的时候可以控制函数跳转到指定的代码中去执行。用过gprof工具应该对gcc的-pg选项不陌生了。

当CONFIG_FUNCTION_TRACER打开时,编译时会增加-pg编译选项,gcc会在每个函数的入口处增加对mcount的调用。
gcc 4.6新增加了-pg -mfentry支持,这样可以在函数的最开始插入一条调用fentry的指令。
通过nm可以看到多了一个未定义的符号fentry

对于动态ftrace,有一个很重要的工作就是记录这些被-pg影响的函数,最终可以通过读debugfs的文件/sys/kernel/debug/tracing/available_filter_functions来查看哪些函数是支持trace的。

编译内核
内核在编译代码时,先指定-pg -fentry选项编译生成.o文件,然后通过scripts/recordmcount.pl脚本来处理.o文件

以一个简单的foo.c文件举例

经过scripts/recordmcount.pl处理之后,.o文件中新增了一个__mcount_loc段,在最终链接时被重定向,里面记录了所有插入了mcount或者fentry的函数地址。

最终内核的链接脚本include/asm-generic/vmlinux.lds.h将__mcount_loc段的内容放在.init.data段中,并且通过__start_mcount_loc和__stop_mcount_loc两个全局符号来访问。

ftrace初始化
gcc的-pg -mfentry选项在每个函数开始处增加了一条callq指令,它和对应的retq据统计会带来13%的性能开销,因此在内核的初始化阶段将这些callq指令全部修改为5 Byte的NOP指令: 66 66 66 66 90H,同时将这些指令的地址记录下来。

scripts/recordmcount.pl过滤了kernel/trace/ftrace.o,没有为其增加__mcount_loc段,所以ftrace代码不会修改其自身的代码。
ftrace_init在start_kernel中调用,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值