Linux内核调试时如何防止变量被优化导致GDB无法查看
内核调试变量被优化的解决方案
内核核心逻辑强依赖默认的-O2优化规则,直接修改顶层Makefile的全局优化参数必然会触发编译、运行异常,可通过以下局部修改的方式避免指定代码的变量被优化:
单个驱动文件指定优化等级
你要调试的arm_smmu_device_probe函数位于drivers/iommu/arm-smmu.c,在同目录的Makefile中添加如下规则,仅对该文件开启调试优化、保留调试信息:CFLAGS_arm-smmu.o += -Og -g其余内核文件仍使用默认的-O2编译,不会触发全局编译错误。
单函数精准控制优化策略
如果你只需要调试这一个函数,可直接给函数添加编译属性,仅修改该函数的优化规则,对其他代码完全无影响,兼容性最高:__attribute__((optimize("Og"), noinline)) static int arm_smmu_device_probe(struct platform_device *pdev) { // 原有函数逻辑 }添加
noinline是为了避免函数被编译器内联,导致GDB无法正常识别断点。如果-Og下仍有变量被优化,可将优化等级替换为O0。最小改动查看指定变量
如果你只需要查看少数几个变量的值,无需修改优化规则,直接给目标变量添加volatile修饰即可强制编译器不优化该变量的存储:volatile struct arm_smmu_device *smmu; volatile struct device *dev = &pdev->dev;
如果不想修改源码,也可以基于对应架构的函数调用约定直接从寄存器读取值:Arm64架构下函数第一个入参存在x0寄存器,你可以在GDB断点触发后执行p (struct platform_device *)$x0拿到pdev的值,再推导dev、smmu的地址即可。
内容的提问来源于stack exchange,提问作者Chan Kim
相关产品推荐
相关产品推荐

