Debian 10下用QEMU调试aarch64程序GDB无法在main断点停住怎么办?
问题根因
你遇到的断点不触发问题是Debian 10自带的QEMU 3.1.0版本的已知bug导致的:
当前版本GCC默认编译生成的是PIE(位置无关可执行)程序,程序运行时的实际加载地址和编译时的符号地址会存在基地址偏移。QEMU 3.1.0在远程调试场景下没有正确把PIE程序的实际加载偏移同步给GDB,你在GDB中设置break main时,断点是打在编译时的符号地址(你输出里的0x76c)上,而非程序实际运行时的main函数地址,所以断点不会被触发,程序直接运行结束。
Ubuntu 20.04自带的QEMU版本高于4.0,已经修复了该问题,所以相同操作可以正常触发断点。
验证方法
你可以执行file a.out确认程序属性,输出中如果包含pie executable就说明是PIE格式程序,符合上述问题触发条件。
解决方案
方案1:编译时禁用PIE(最简单快捷)
修改编译命令,添加禁用PIE的编译选项即可:
aarch64-linux-gnu-gcc -O0 -g3 -fno-pie -no-pie main.c
重新编译后再按原步骤调试,断点即可正常触发。
方案2:升级QEMU版本
你可以选择以下两种方式升级:
- 升级系统到Debian 11(bullseye),自带的QEMU 5.2版本已修复该问题
- 自行编译安装5.0以上版本的QEMU替换当前系统的旧版本
方案3:手动计算实际地址设置断点
如果不想修改编译选项也不想升级QEMU,也可以手动计算地址打断点:
GDB连接到QEMU后,先执行info files找到.text段的实际加载起始地址,加上main函数在程序中的偏移量(你输出中的0x76c)得到实际运行地址,再对该地址设置断点即可生效。
内容的提问来源于stack exchange,提问作者Pavel.Zh
相关产品推荐
相关产品推荐

