ARM汇编中GDB执行bl分支后意外持续运行的问题与解决
问题解答
一、push指令引发GDB step over异常的原因
你碰到的是GDB 7.7.1版本在ARMv6l架构下的调试bug。GDB的n(step over)命令逻辑是:执行bl调用子例程时,会在lr指向的返回地址(也就是bl后的下一条指令)临时设断点,等子例程执行bx lr返回时触发这个断点,GDB就会停在返回后的指令。但ARMv6的push {r0}属于栈操作,会修改sp寄存器,老版本GDB对这类栈操作的处理存在缺陷,导致临时断点的设置或触发逻辑出错,最终表现为n命令直接跳到下一个已存在的断点,而非停在bl之后的指令。
二、实际项目中无需单步子例程仍能存返回值到栈的解决方法
有几种可行方案:
- 用
finish命令替代n:当执行到bl指令时,输入finish,GDB会自动跑完当前子例程并停在bl后的下一条指令,不管子例程里有没有栈操作,既不用单步遍历子例程,也能让子例程正常完成push {r0}的操作。 - 升级GDB版本:GDB 7.7.1是2014年的老版本,后续8.x及以上版本修复了大量ARM架构下的调试bug,升级后
n命令的step over行为会恢复正常,子例程的栈操作也不会影响调试。 - 手动设置返回断点:提前在
bl指令的下一条指令地址处设断点(用b *0xXXXXXXX命令,地址替换为实际返回指令地址),然后输入c命令让程序运行到该断点,同样可以跳过子例程单步,同时保留栈操作逻辑。
内容的提问来源于stack exchange,提问作者s7a19t4r
相关产品推荐
相关产品推荐

