没有设置断点为什么会出现SIGTRAP信号?是隐藏的硬件断点吗?

28

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

SIGTRAP,跟踪/断点陷阱

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

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


重置CPU。 :) (如果gdb死机或在退出/重新连接时没有删除所有现有的断点,则可以保留hw断点安装)。 - dbrank0
请注意,调试寄存器可能会在某些类型的重置过程中保留。但是完全的上电复位肯定会清除它。 - TJD
1
“full power-on reset” 是什么意思?我尝试了拔插电源线,但断点仍然存在。 - Randomblue
所以,如果我理解正确,您已经在嵌入式系统上循环电源(并且没有备用电池),关闭了JTAG接口/ICE的电源,但断点仍然被触发了? - dbrank0
如果CPU正在进行完整的电源循环,您就无法触发硬件断点。这一定是代码中的某些问题。 - mikehabibi
显示剩余2条评论
5个回答

23

好的。长话短说: 硬件断点通常是通过写入一些特殊的CPU寄存器来设置的,这是由gdb完成的。如果gdb崩溃了,则可能会在CPU中留下这些已经安装的断点。 我猜你的实现(gdb)在连接到目标时没有清除或检查它们。 要找到它们,您需要列出CPU上硬件断点寄存器的内容(不知道如何在STM32上执行此操作)。解决方法是(有根据的猜测):使用gdb设置几个HW断点(通常只有少数,很少超过8个),然后将所有断点都删除。这应该重写并清除那些硬件寄存器。一旦您设置了这些断点(在删除它们之前),请执行“continue”(以防万一,因为gdb仅在那个时候设置断点)。


1
谢谢您提供关于设置多个断点然后再删除它们的建议。那应该能解决问题。有一点烦人的是当gdb连接到我的目标时,它没有清除那些断点。 - Randomblue

8
以下是帮助我解决问题的方法:
# 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.

3
这与被接受的答案是相同的思路,但值得注意的是 hbreak 命令非常关键。普通的 break 命令会设置软件断点而不是覆盖以前的断点。 - Samuel Peter
1
这个答案需要更多的赞。它很有效,并且是“烹饪书”。我在Linux / Wine下调试MinGW-w64应用程序时遇到了一些奇怪的SIGTRAP断点,但我并没有设置。这个答案立即解决了我的问题。 - kevinarpe

3

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

通过检查您的指令指针来调试此问题,最有可能指向一个包含BKPT指令的地址(您将需要查找实际代码)。

从那里开始,您将根据堆栈和指令指针向后工作,并查看是否在预期位置。 这可能会有许多原因,例如GDB插入未能清除的断点指令,或者内存损坏。


1
如果添加和删除硬件断点无法解决问题,请检查中断向量表。在Cortex-M微控制器上,所有处理程序入口都应该有奇数地址(ARM Cortex-M FAQ)。如果没有,则会触发类型为INVSTATE的UsageFault,并使MCU停止运行。GDB将其解释为SIGABRT。
如果其中一个入口具有偶数地址,请检查处理程序函数是否具有.thumb_func和.type指令(NXP Avoid hardfaultHardFault and .thumb_func)。
以下是HardFault_Handler的示例:
.thumb_func
.type HardFault_Handler, %function
HardFault_Handler:
  TST LR, #4
  ITE EQ
  MRSEQ R0, MSP
  MRSNE R0, PSP
  B hard_fault_handler_c

0

您正在运行的代码可能包含以下内容:

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

这会调用一个SIGTRAP信号。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接