c-SIGTRAP,尽管没有设置断点;隐藏的硬件断点



我正在为STM32嵌入式系统调试这段软件。在其中一个函数中,我的程序不断碰到某种断点:

跟踪/断点陷阱

然而,在GDB中,当我执行info breakpoints时,我得到No breakpoints or watchpoints。断点实际上对应于我很久以前在可执行文件的另一个版本中设置的断点。当我设置断点时,GDB告诉我automatically using a hardware breakpoint on read-only memory(或类似的消息)。

我认为硬件断点仍然存在于我的芯片上,尽管我已经加载了新版本的软件。如果确实存在虚假断点,我该如何定位和删除它?

好的。长话短说:硬件断点通常通过写入一些特殊的CPU寄存器来设置。这是由gdb完成的。如果gdb死了,它可以把那些安装在CPU中的东西留下。我想您的(gdb)实现在连接到您的目标时并没有明确或检查这些。要找到它们,您需要列出CPU上硬件断点寄存器的内容(不知道如何在STM32上做到这一点)。解决方法(知情猜测)是这样的:使用gdb设置几个HW断点(通常只有几个,很少超过8个),然后删除所有断点。这应该覆盖然后清除那些hw寄存器。一旦设置了这些断点(在删除它们之前),就要"继续"(以防万一,因为gdb只在那个时候设置断点)。

以下帮助了我:

# Ones I hit the SIGTRAP:
(gdb) f 0  # Show the current stack frame of the current thread.
#0  0x4003ed70 in pthread_create@@GLIBC_2.4 () from /opt/CodeSourcery/arm-2011.09/arm-none-linux-gnueabi/libc/lib/libpthread.so.0
# The fragment of interest is the current address: 0x4003ed70.
# Set the hardware assisted breakpoint at the current address:
(gdb) hbreak *0x4003ed70
# Continue execution (without hitting SIGTRAP):
(gdb) c
# Continuing.

SIGTRAP应该是正在运行的断点指令。

通过检查指令指针进行调试,它很可能指向包含BKPT指令的地址(您必须查找实际代码)。

从那时起,你必须根据堆栈和指令指针进行反向操作,看看你是否达到了预期的目标。可能有很多原因导致了这种情况,从GDB插入一条无法清除的断点指令,到内存损坏。

如果添加和删除硬件断点没有帮助,请检查中断向量。

在Cortex-M微控制器上,所有处理程序条目都应该有一个奇数地址(ARM Cortex-M常见问题解答)。如果没有,则会触发类型为INVSTATE的UsageFault,并停止MCU。GDB将其解释为SIGABRT。

如果其中一个条目具有偶数地址,则检查处理程序函数是否具有.tumb_func.type指令(NXP避免硬故障、硬故障和.tumb_func)。

硬故障处理程序示例:

.thumb_func
.type HardFault_Handler, %function
HardFault_Handler:
  TST LR, #4
  ITE EQ
  MRSEQ R0, MSP
  MRSNE R0, PSP
  B hard_fault_handler_c

您正在运行的代码可能包含

int $0x03 ; talking about x86, don't know STM32 mnemo

其调用SIGTRAP。

最新更新