Debugging 如何在ARM处理器上设置软件断点?

Debugging 如何在ARM处理器上设置软件断点?,debugging,assembly,gdb,arm,Debugging,Assembly,Gdb,Arm,如何执行与x86软件中断等效的操作: asm( "int $3" ) 在ARM处理器(特别是Cortex A8)上生成事件以中断gdb下的执行?ARM没有定义特定的断点指令。在不同的操作系统中可能会有所不同。在ARM Linux上,它通常是ARM模式下的UND操作码(例如,FE DE FF E7)和Thumb模式下的BKPT(BE) 有了GCC编译器,您通常可以使用\uuuu builtin\u trap()内在函数来生成特定于平台的断点。另一个选项是使用arm-none-eabi-gdb.e

如何执行与x86软件中断等效的操作:

asm( "int $3" )

在ARM处理器(特别是Cortex A8)上生成事件以中断gdb下的执行?

ARM没有定义特定的断点指令。在不同的操作系统中可能会有所不同。在ARM Linux上,它通常是ARM模式下的UND操作码(例如,
FE DE FF E7
)和Thumb模式下的BKPT(
BE


有了GCC编译器,您通常可以使用
\uuuu builtin\u trap()
内在函数来生成特定于平台的断点。另一个选项是使用arm-none-eabi-gdb.exe交叉编译器提高(SIGTRAP),这对我来说非常有用(感谢Igor的回答):


对于ARM上的Windows,instrinsic
\uuu debugbreak()
仍然可以使用未定义的操作码

nt!DbgBreakPointWithStatus:
defe     __debugbreak
我有一个简单的库()用于此:

#include <debugbreak.h>
...
debug_break();
#包括
...
debug_break();

只需将单个
debugbreak.h
头复制到代码中,它就能正确处理ARM、AARC64、i386、x86-64甚至MSVC

请参阅man entry.

在我的armv7hl(linux 4.1.15的i.MX6q)系统上,要在另一个进程中设置断点,我使用:

ptrace(ptrace_POKETEXT,pid,地址,0xe7f001f0)

我在选择gdb之后选择该值:)


这非常有效:我可以检查跟踪的进程,恢复原始指令,并使用PTRACE_CONT重新启动进程。

尽管最初的问题是关于Cortex-A7(ARMv7-A)的,它在ARMv8 GDB上使用

brk#0


我们可以使用断点指令:

  • 对于A32:使用 指示

  • 手臂和拇指:使用说明


或者我们可以使用伪指令生成未定义的指令,如果处理器试图执行该指令,将导致异常。

使用BKPT指令生成的SIGBUS似乎会弄乱程序计数器。使用swi指令,我相信svc是该指令的另一个名称,具体取决于arm的风格。SWI指令依赖于操作系统/调试器。Angel调试器将代码0x18定义为ReportException,将子代码0x20020定义为断点。它不是便携式的。如果程序集不采用args.GCC/clang,则不需要使用
volatile
,假定
\uuuu builtin\u trap()
之后的代码是不可访问的,即使在
-O0
。在上,我们可以看到,对于ARM,在函数末尾的
.inst 0xe7f000f0
之后没有任何内容,甚至没有
bx lr
。在x86上,它编译为ud2(非法指令),同样省略了用于实现后续C语句的代码。即使在
-O0
,ARM gcc8.2仍然省略了函数尾声,尽管后面的C语句中有代码。但这使它无法使用。@PeterCordes:我建议将它置于运行时状态。@yfr24493AzzrggAcom你可以问一个关于我朋友的新问题。我已经问过了,但没有得到一个好的答案,那就是指令修复只针对armv7,或者也可能针对ARMV4?在第一个项目中,你可能是指A64,而不是A32?然后,我认为第二个项目应该是“针对A32和T16”
#include <debugbreak.h>
...
debug_break();