繁体   English   中英

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

[英]SIGTRAP despite no set breakpoints; hidden hardware breakpoint?

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

SIGTRAP,跟踪/断点陷阱

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

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

好的。 长答案:硬件断点通常是通过写入一些特殊的 CPU 寄存器来设置的。 这是由 gdb 完成的。 如果 gdb 死了,它可以留下那些安装在 CPU 中的。 我猜你的实现(gdb)在连接到你的目标时既没有清除也没有检查它们。 要找到它们,您需要列出 CPU 上硬件断点寄存器的内容(不知道如何在 STM32 上执行此操作)。 解决方法是(知情的猜测)是这样的:使用 gdb 设置几个硬件断点(通常只有几个,很少超过 8 个),然后将它们全部删除。 这应该覆盖然后清理这些硬件寄存器。 一旦你设置了这些断点(在删除它们之前),做“继续”(以防万一,因为 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 FAQ )。 如果没有,则触发类型为 INVSTATE 的 UsageFault 并暂停 MCU。 GDB 将此解释为 SIGABRT。

如果条目之一具有偶数地址,则检查处理函数是否具有.thumb_func.type指令( NXP 避免 hardfaultHardFault 和 .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

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

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

它调用一个 SIGTRAP。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM