GDB中next/step被宏内__BKPT中断时hook-stop未触发问题
STM32调试中GDB步进时__BKPT绕过hook-stop的异常行为
环境
- 目标芯片:STM32L475VGT(ST-Link)
- GDB版本:GNU gdb (GNU Tools for STM32 14.3.rel1.20251027-0700) 15.2.90.20241229-git
- IDE:STM32CubeIDE for VSCode v3.9.0
复现步骤
- 定义包含
__BKPT的C宏:
#include "cmsis_gcc.h" #define DEBUGGER_ATTACHED() ((CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) != 0) #define BREAKPOINT(arg) do { if (DEBUGGER_ATTACHED()) { __BKPT(arg); __NOP(); /* NOP to prevent the debugger from immediately stepping to the next line. */ } } while (0) int main() { int a = 0; // 操作:继续(F5) BREAKPOINT(0x01); // 操作:单步跳过(F10),此步正常 a++; // 操作:单步跳过(F10),此步正常 BREAKPOINT(0x01); // 操作:单步跳过(F10),IDE进入"悬停"状态 a++; }
- 在
.gdbinit文件中定义hook脚本:
define hook-next echo ---> hook-next end define hookpost-next echo ---> hookpost-next end define hook-stop echo ---> hook-stop # 检测ARM Thumb __BKPT指令 if (*(unsigned char*)($pc+1)) == 0xBE # 读取__BKPT参数 set $arg = *(unsigned char*)($pc) if $arg == 0x01 # 跳过BKPT指令(16位);否则PC会停留在断点指令上,无法执行单步跳过、单步进入、继续等操作 set $pc = $pc + 2 echo ---> __BKPT(0x01) handled end end end
- 启动调试会话,对第二个
BREAKPOINT(0x01)行执行单步跳过(F10/next)。
现象
对正常代码行(如a++)执行next时,会依次触发hook-next、next、hookpost-next、hook-stop;但对宏内BREAKPOINT(0x01)执行next时,hook-stop未触发,GDB陷入“悬停”状态:IDE显示调试正在运行,但CPU已暂停,需手动执行暂停(F6)才会触发hook-stop。
技术分析
GDB将宏上的next/step操作视为原子事务,若CPU在到达next/step计算的目标地址前触发__BKPT产生SIGTRAP,GDB会终止该事务,未完成停止流程,导致hook-stop被绕过,严重影响依赖hook-stop的自动化脚本(如PC调整)。
期望行为
无论目标因步进完成还是中途遇到__BKPT暂停,GDB都应触发hook-stop。
内容的提问来源于stack exchange,提问作者Parminder Singh
相关产品推荐
相关产品推荐

