简体   繁体   English

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

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

I am debugging this piece of software for an STM32 embedded system.我正在为 STM32 嵌入式系统调试这块软件。 In one of the functions my programs keeps hitting some sort of breakpoint:在其中一个函数中,我的程序不断遇到某种断点:

SIGTRAP, Trace/breakpoint trap SIGTRAP,跟踪/断点陷阱

However, in GDB, when I do info breakpoints I get No breakpoints or watchpoints .但是,在 GDB 中,当我执行info breakpoints我得到No breakpoints or watchpoints The breakpoint actually corresponds to a breakpoint I had set quite some time ago, in another version of the executable.该断点实际上对应于我很久以前在另一个版本的可执行文件中设置的断点。 When I set that breakpoint, GDB told me automatically using a hardware breakpoint on read-only memory (or a similar message).当我设置该断点时,GDB 会automatically using a hardware breakpoint on read-only memory告诉我automatically using a hardware breakpoint on read-only memory (或类似消息)。

I think the hardware breakpoint remains on my chip, despite having loaded a new version of the software.我认为硬件断点仍然在我的芯片上,尽管加载了新版本的软件。 If there is indeed a spurious breakpoint, how can I locate and remove it?如果确实存在虚假断点,我该如何定位并删除它?

Ok.好的。 Long answer: Hardware breakpoints are usually set by writing to some special CPU registers.长答案:硬件断点通常是通过写入一些特殊的 CPU 寄存器来设置的。 This is done by gdb.这是由 gdb 完成的。 If gdb dies, it can left those installed in CPU.如果 gdb 死了,它可以留下那些安装在 CPU 中的。 I guess your implementation (of gdb) does not either clear or examine those, when it connects to your target.我猜你的实现(gdb)在连接到你的目标时既没有清除也没有检查它们。 To locate them, you would need to list the contents of hardware breakpoints registers on your CPU (don't know how to do this on STM32).要找到它们,您需要列出 CPU 上硬件断点寄存器的内容(不知道如何在 STM32 上执行此操作)。 Workaround would be (informed guess) be this: set few HW breakpoints (typically there are only a few, seldom more than 8) using gdb, then remove all of them.解决方法是(知情的猜测)是这样的:使用 gdb 设置几个硬件断点(通常只有几个,很少超过 8 个),然后将它们全部删除。 This should overwrite and then clean those hw registers.这应该覆盖然后清理这些硬件寄存器。 Once you do set those breakpoints (before removing them), do "continue" (just in case, as gdb sets breakpoints only at that time).一旦你设置了这些断点(在删除它们之前),做“继续”(以防万一,因为 gdb 只在那个时候设置断点)。

The following helped me:以下帮助了我:

# 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 should be a breakpoint instruction that's being run. SIGTRAP 应该是正在运行的断点指令。

Debug this by inspecting your instruction pointer, it's most likely pointed at an address that contains the BKPT instruction (you'll have to look up what the actual code is).通过检查您的指令指针来调试它,它很可能指向包含 BKPT 指令的地址(您必须查找实际代码是什么)。

From there you'll have to work backwards based on the stack and instruction pointer and see if you're where you expect to be.从那里你必须根据堆栈和指令指针向后工作,看看你是否在你期望的地方。 There could be a number of things causing this, from GDB inserting a breakpoint instruction that it failed to clear, to memory corruption.可能有很多原因导致这种情况,从 GDB 插入未能清除的断点指令到内存损坏。

If adding and removing hardware breakpoints does not help, check the interrupt vector.如果添加和删除硬件断点没有帮助,请检查中断向量。

On Cortex-M microcontrollers all handler entries should have an odd address ( ARM Cortex-M FAQ ).在 Cortex-M 微控制器上,所有处理程序条目都应该有一个奇数地址( ARM Cortex-M FAQ )。 If they don't, then a UsageFault of type INVSTATE is triggered and the MCU is halted.如果没有,则触发类型为 INVSTATE 的 UsageFault 并暂停 MCU。 GDB interprets this as a SIGABRT. GDB 将此解释为 SIGABRT。

If one of the entries has an even address, then check if the handler function has the .thumb_func and .type directives ( NXP Avoid hardfault , HardFault and .thumb_func ).如果条目之一具有偶数地址,则检查处理函数是否具有.thumb_func.type指令( NXP 避免 hardfaultHardFault 和 .thumb_func )。

Example for a HardFault_Handler: 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

The code you are running may contain您正在运行的代码可能包含

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

which invokes a SIGTRAP.它调用一个 SIGTRAP。

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

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