微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何跳过 TRACE32 中的软件断点

如何解决如何跳过 TRACE32 中的软件断点

我正在编写在 ARM Cortex M3 上运行的代码。我正在使用与 TRACE32 软件包配合使用的劳特巴赫调试器。

我按照 ARM 的建议 (https://www.keil.com/support/man/docs/armcc/armcc_chr1359124993371.htm) 插入一个软件断点,如下所示:

易失性 uint16_t haris_4=0;

void function(void)
{
    haris_4 = 1;
    __breakpoint(0);
    haris_4 = 2;
...

然后我转到 TRACE32 调试器并观察 haris_4 变量的值。它的值为 1。这意味着断点实际上已命中。

我试图越过断点并继续执行程序,但我不能。 trace32 Single Step、Step over Call 和 Go 的按钮不起作用。

有什么想法可以跳过软件断点并继续执行吗?

解决方法

虽然这个问题听起来很简单,但实际上有几个方面需要考虑:

  1. 为什么有人想要在他/她的中设置断点指令 代码?
  2. 执行断点时处理器是否处于调试模式 说明?
  3. 是否使用了相当旧版本的 TRACE32?

注意:当您在 C/C++ 中编写 __breakpoint(0) 时,编译器实际上会为其创建汇编指令 BKPT 0。 (您可以通过点击 TRACE32 中列表窗口的“模式”按钮来检查汇编代码。)

所以首先:在你的源代码中有 __breakpoint(0) 有充分的理由吗?我倾向于说:不,在正常情况下,静态断点指令在内部没有意义应用程序代码。 如果您想在某个指令处停下来观察您的变量,请使用命令 Break.Set 在 TRACE32 中设置断点或转到菜单 → Break → Set...
如果需要在 flash 内部设置断点,调试器会自动设置片上断点。 (TRACE32 还允许您在 Flash 中设置软件断点,如果您真的想要这样做的话(但这有点棘手)。)

但是,如果您真的希望在源代码中包含 __breakpoint(0),那么让我们看看为什么这可能无法如您所愿...

我们来看第二点:执行断点指令时处理器是否处于调试模式?
如果在连接调试器之前执行代码,则在执行 BKPT 指令时,您的 CPU 可能未处于调试模式。在这种情况下,CPU 将跳转到异常向量。根据您对调试停止控制和状态寄存器 (DHCSR) 的配置,这将是 DebugMonitor 或 HardFault 异常。在这两种情况下,您的程序计数器可能不再在您的函数中,并且当您按下 TRACE32 中的步进按钮时,会执行一些完全不同的代码。 (在“ARMv7-M Architecture Reference Manual”的“调试事件行为”一章中阅读有关此内容的更多信息)
当您点击 TRACE32 中的步进按钮时,请检查您的程序计数器 (PC) 是否仍然指向 BKPT 指令。 (例如在菜单→查看→注册中检查PC的值。)如果PC值很好,这可能是另一个问题...

最后:您的 TRACE32 版本是否相当旧?在这种情况下我们可以做什么...

当 Cortex-M CPU 在调试模式下执行 BKPT 指令时,CPU 将在该 BKPT 指令处停止并且程序计数器 (PC) 将指向该 BKPT 指令。此外,单步执行 BKPT 指令将使 PC 停留在 BKPT 指令上。虽然如果 BKPT 指令是由调试器动态插入的,CPU 的这种行为很好,但如果 BKPT 指令是故意添加到源代码中的,则可能会很烦人,因为您无法跳过它。

因此,当执行 BKPT 指令时,TRACE32 做了一个小技巧,将程序计数器设置为 BKPT 指令下方的指令。因此,BKPT 指令在单步执行时的行为类似于 NOP。
但是,您必须使用 TRACE32 版本 R.2014.09 或更新版本。

如果您的 TRACE32 版本较旧(因此您自 6 年以来一直没有更新),那么您仍然可以使用 PRACTICE 脚本使其正常工作:

  • 创建一个文本文件并命名,例如myfix.cmm
  • 在该文本文件中输入以下两行代码:
    IF (ADDRESS.INSTR.LEN(P:R(PP))==2)&&((DATA.WORD(P:R(PP))&0xff00)==0xbe00)
    Register.Set PP R(PP)+2
    此脚本检查当前程序指针 (PP) 处的指令是否具有两个字节的大小,以及它是否具有 BKPT 指令的 Thumb 机器代码。如果是,脚本会将程序指针增加 2(“跳转”到下一条指令)。
  • 在TRACE32命令行中执行以下命令:
    GLOBALON PBREAK DO myfix.cmm
    该命令将在程序执行停止时运行您的脚本 myfix.cmm,例如因为 BKPT 指令。您可能需要将该 GLOBALON 命令添加到您执行的 PRACTICE 脚本中以启动调试会话。
  • 就是这样:下次 CPU 因 BKPT 指令而停止时,它会感觉它在 BKPT 指令之后停止并且在步进时表现得像一个 NOP。

但是,如果您已经使用了 2015 年或更新版本的 TRACE32,还请检查 TRACE32 中的窗口 PMACRO,以确保没有人或您的同事用另一种 GLOBALON PBREAK 处理程序恶作剧....>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。