SIGTRAP尽管没有设置断点;隐藏的硬件断点?

时间:2012-03-23 10:26:37

标签: c gdb embedded breakpoints stm32

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

  

SIGTRAP,跟踪/断点陷阱

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

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

5 个答案:

答案 0 :(得分:21)

确定。答案很长: 硬件断点通常通过写入一些特殊的CPU寄存器来设置。这是由gdb完成的。如果gdb死掉,它可以将那些安装在CPU中。 我猜你的(gdb)实现在连接到你的目标时不会清除或检查它们。 要找到它们,您需要在CPU上列出硬件断点寄存器的内容(不知道如何在STM32上执行此操作)。解决方法是(通知猜测)是这样的:使用gdb设置几个硬件断点(通常只有少数几个,很少超过8个),然后删除所有断点。这应该覆盖然后清理那些hw寄存器。一旦设置了这些断点(在删除它们之前),请执行“continue”(以防万一,因为gdb仅在那时设置断点)。

答案 1 :(得分:4)

以下帮助了我:

# 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.

答案 2 :(得分:3)

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

通过检查指令指针来调试它,它很可能指向包含BKPT指令的地址(你必须查找实际代码是什么)。

从那里你必须根据堆栈和指令指针向后工作,看看你是否在你想要的位置。从GDB插入一个无法清除的断点指令到内存损坏,可能会导致这种情况。

答案 3 :(得分:1)

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

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

调用SIGTRAP。

答案 4 :(得分:1)

如果添加和删除硬件断点无效,请检查中断向量。

在Cortex-M微控制器上,所有处理程序条目都应具有奇数地址(ARM Cortex-M FAQ)。如果他们没有,则触发INVSTATE类型的UsageFault并停止MCU。 GDB将此解释为SIGABRT。

如果其中一个条目具有偶数地址,则检查处理函数是否具有 .thumb_func .type 指令(NXP Avoid hardfault,{{ 3}})。

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