【问题标题】:Can't step in GDB past Thumb/ARM transition, ARM breakpoints are not set无法通过 Thumb/ARM 转换进入 GDB,未设置 ARM 断点
【发布时间】:2013-03-01 20:31:20
【问题描述】:

我正在 Android 1.6 模拟器上调试一个没有符号的程序。在加载 SO 库期间出现崩溃(信号),我正在尝试追踪它。崩溃发生在库启动代码的某个地方,我知道的很多。在控制从加载程序转到 SO 之前,我知道 SO 加载程序代码中的安全位置。我可以在那里设置一个断点,然后一直到 BLX 进入库。加载程序的代码是 Thumb。库启动代码是ARM。

由于没有符号,我使用set arm force-mode xxx 让GDB 知道。在启动导致加载程序停止的序列之前,我将模式设置为 Thumb。

但问题是,当我来到 BLX 指令并尝试单步执行 (si) 时,调试器不会在下一条指令处停止 - 它一直到信号.即使我在 BLX 上执行 si 之前先执行 set arm force-mode arm,似乎也无所谓。

在库启动代码中设置断点也无济于事。我不确定 GDB 究竟是如何设置断点的,但看起来当前执行代码的模式与预期的断点目标模式之间的不匹配是一个障碍。

编辑:我什至尝试对正在运行的代码进行猴子修补,以便在正确的位置使用 BKPT 命令 - GDB 仍然没有中断。

EDIT2:猴子修补代码部分似乎不起作用。不过,我可以将数据部分的一部分用作暂存区。尽管如此,BKPT 不会导致 GDB 崩溃...


EDIT3:对三行代码 sn-p 使用暂存数据区域,我可以切换出 Thumb 并在信号中返回 GDB。但是,现在我处于 ARM 模式,GDB 由于某种原因无法设置断点。

BLX 进入库命令如下所示:blx r2。 r2 的值为 0x80601b60 - 这是库启动例程。

当我停止使用 BLX 时,我会这样做。我在数据部分有一个暂存区。我将以下 ARM 命令放在那里:

mov r12, 0 ; the value of r12 will be soon ruined by the code anyway
ldr r12, [r12] ; Provoke a SIGSEGV to stop GDB in ARM mode
mov pc, r2 ; To resume back into the library

然后我将r2的值强行设置为我的暂存区,将GDB模式设置为ARM并继续。划痕区的一个 SIGSEGV 自然被抛出。

我在这里,处于 ARM 模式(CPU 和 GDB 的强制模式)。我在 0x80601b60 - 库入口点设置了一个断点。我将 r2 的值改回 0x80601b60 以便第三条命令跳转到那里。我将 r12 的值更改为有效读取地址,以便在重试时不会重新抛出信号。然后我发出signal 0 命令在没有信号的情况下继续。

我预计控制会转到 0x80601b60 并且会遇到断点。它不是。为什么不? mov 的语义在分配给 pc 时是否有所不同(就像 ldr rx, [pc] 一样)?

mov pc, r2 上设置断点也不起作用。在信号模式停止时在 GDB 中设置断点是否有问题?但即使我在信号之前设置断点(在 Thumb 模式下),它也不起作用。

更奇怪的是,我遇到了控制越过mov pc, r2 的情况,就好像它根本没有执行一样。但是,一旦我修复了 r12,就会执行上一条指令

signal 0 有单步模拟吗?

【问题讨论】:

  • 试试set arm force-mode autoset arm fallback-mode auto。这应该检查 CPSR。 BLX 的问题是,GDB 通常会将illegal 指令放在下一个执行点到单步。如果它对模式感到困惑,那么它可能会编写一个illegal ARM vs Thumb 指令。由于 ICACHE/DCACHE 等原因,补丁代码有问题。我不知道猴子补丁是什么意思,但您需要遵循 SMC 程序。见:en.wikipedia.org/wiki/Self-modifying_code
  • 不,仍然失败:(
  • 确实如此,但 Android 上的每个代码部分也是如此。在maps 中标记为r-xp
  • 你能否通过写入 PC/LR/CPSR 然后告诉 GCC 它处于 ARM 模式来“手动模拟”BLX 指令?
  • 不,也不行。

标签: linux debugging android-ndk gdb arm


【解决方案1】:

这是由 GDB 中的错误引起的。我现在正在准备修复。看 https://code.google.com/p/android/issues/detail?id=56962

[已编辑;最初,我链接到了错误的 URL,如我在下面的回复中所解释的。现在上面的网址是正确的。]

您可以挑选我提交的 gerrit,也可以等待 Google 发布更新的 NDK。或者,如果您在 x86 上使用 Linux 或 Windows,我可能会共享一个二进制文件。

Gerrit 提交的是:https://android-review.googlesource.com/#/c/61322/

【讨论】:

  • 我很抱歉花了这么长时间。事实上,我上面列出的错误报告是针对一个稍微不同的问题——step 而不是 stepi——并且有不同的原因。对于您的实际问题,我将在下面提供不同的答案。
  • 我接受,但我没有尝试该补丁 - 我最初尝试调试的潜在问题已通过其他方式解决。
  • 同时,类似的问题仍然存在于 GDB 8.1 中(您可以步进,但不能设置拇指断点),但在 GDB 8.3 中已修复。 JFYI。他们似乎一次又一次地打破和修复它......
猜你喜欢
  • 1970-01-01
  • 2013-03-28
  • 1970-01-01
  • 1970-01-01
  • 2013-08-18
  • 2018-09-18
  • 2018-07-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多