如何捕获调试器并在 iOS 硬件上继续?
How can I trap to the debugger and continue on iOS hardware?
在 Mac OS X 和 iOS 模拟器(均为 x86)中,我们可以使用内联的 int3
指令陷入调试器 (LLDB)部件。这很好,因为它会陷入特定的代码行,但我们可以通过在调试器中点击继续来立即继续。
有没有办法在 iOS 硬件上执行此操作?
An answer to an older question mentions raise(SIGINT)
which as far as I can see (from examining signal.h
) does not exist. Another answer mentions the trap
assembly instruction, which causes a build error ("Unrecognized instruction mnemonic"). Also unrecognized is the BKPT
assembly instruction mentioned in ARM documentation.
我已经尝试了 __builtin_trap()
,这几乎可以满足我的要求,但不允许我继续。我一直点击它,除非我使用 jump +1
或 register write pc `$pc+8\`
手动推进指令指针,这比点击继续要方便得多。
我正在使用 Xcode 7.3.1 为 32 位和 64 位设备构建 iOS 9。感谢您的帮助!
Apple 的 libc signal.h
includes XNU's sys/signal.h
, 定义了 SIGINT(在所有平台上):
// [...]
#define SIGHUP 1 /* hangup */
#define SIGINT 2 /* interrupt */
#define SIGQUIT 3 /* quit */
// [...]
因此,虽然我无法确认这种做法是否确实有效(由于我缺少 iOS 9 设备),但阻碍您的障碍实际上应该不是问题。
至于汇编指令,BKPT
是有效的 ARM 指令,但仅适用于 A32。 A64 变体称为 BRK
.
如果您正在构建胖二进制文件并无条件地使用其中任何一个,您将始终 运行 进入编译器错误。
另请注意,这两条指令都需要一个立即值(传递给调试器)。省略该值也会产生编译器错误。
也就是说,您应该能够使用简单的 #ifdef
:
为 A32 和 A64 插入调试指令
#ifdef __aarch64__
asm volatile("BRK 0");
#else
asm volatile("BKPT 0");
#endif
您可以将 0
替换为您在 0
和 255
之间选择的任何值。
关于 TRAP
指令的说明:虽然 Apple 的汇编程序似乎接受 A32 的这条指令并将其转换为 0xe7ffdefe
,但它会在 A64 上发出 "unrecognized instruction mnemonic",类似于BKPT
指令。
我也无法在 ARM 信息中心或 Apple 的文档中找到对说明的任何参考。
我在 OS X 上使用 Swift 时遇到了类似的问题:
1) raise(SIGINT)
在后台进程中对我不起作用(例如:SceneKit 的场景渲染器协议)。 (也许缺少处理程序?)
2) __builtin_trap()
不允许在之后继续
3) asm(" int3 ")
需要 ObjC 和头文件,一开始吓了我一跳。但还算不错。刚刚在两个新文件中添加了三行:
---- NSObject+MachineTrap.h ----
void machineTrap(void);
---- NSObject+MachineTrap.h ----
#import "NSObject+MachineTrap.h"
void machineTrap(void) { asm (" int3 "); } /// Program has TRAPPED to DEBUGGER ///`
(我选择 int3
而不是 BRK
、BKPT
、SVC
可能不正确。)
我在使用基于 ARM 的 MacBook Pro(Apple M1 芯片)时遇到了类似的问题。这对我有用:
asm ("brk #0xF000");
这也适用于 iOS 设备。
在 Mac OS X 和 iOS 模拟器(均为 x86)中,我们可以使用内联的 int3
指令陷入调试器 (LLDB)部件。这很好,因为它会陷入特定的代码行,但我们可以通过在调试器中点击继续来立即继续。
有没有办法在 iOS 硬件上执行此操作?
An answer to an older question mentions raise(SIGINT)
which as far as I can see (from examining signal.h
) does not exist. Another answer mentions the trap
assembly instruction, which causes a build error ("Unrecognized instruction mnemonic"). Also unrecognized is the BKPT
assembly instruction mentioned in ARM documentation.
我已经尝试了 __builtin_trap()
,这几乎可以满足我的要求,但不允许我继续。我一直点击它,除非我使用 jump +1
或 register write pc `$pc+8\`
手动推进指令指针,这比点击继续要方便得多。
我正在使用 Xcode 7.3.1 为 32 位和 64 位设备构建 iOS 9。感谢您的帮助!
Apple 的 libc signal.h
includes XNU's sys/signal.h
, 定义了 SIGINT(在所有平台上):
// [...]
#define SIGHUP 1 /* hangup */
#define SIGINT 2 /* interrupt */
#define SIGQUIT 3 /* quit */
// [...]
因此,虽然我无法确认这种做法是否确实有效(由于我缺少 iOS 9 设备),但阻碍您的障碍实际上应该不是问题。
至于汇编指令,BKPT
是有效的 ARM 指令,但仅适用于 A32。 A64 变体称为 BRK
.
如果您正在构建胖二进制文件并无条件地使用其中任何一个,您将始终 运行 进入编译器错误。
另请注意,这两条指令都需要一个立即值(传递给调试器)。省略该值也会产生编译器错误。
也就是说,您应该能够使用简单的 #ifdef
:
#ifdef __aarch64__
asm volatile("BRK 0");
#else
asm volatile("BKPT 0");
#endif
您可以将 0
替换为您在 0
和 255
之间选择的任何值。
关于 TRAP
指令的说明:虽然 Apple 的汇编程序似乎接受 A32 的这条指令并将其转换为 0xe7ffdefe
,但它会在 A64 上发出 "unrecognized instruction mnemonic",类似于BKPT
指令。
我也无法在 ARM 信息中心或 Apple 的文档中找到对说明的任何参考。
我在 OS X 上使用 Swift 时遇到了类似的问题:
1) raise(SIGINT)
在后台进程中对我不起作用(例如:SceneKit 的场景渲染器协议)。 (也许缺少处理程序?)
2) __builtin_trap()
不允许在之后继续
3) asm(" int3 ")
需要 ObjC 和头文件,一开始吓了我一跳。但还算不错。刚刚在两个新文件中添加了三行:
---- NSObject+MachineTrap.h ----
void machineTrap(void);
---- NSObject+MachineTrap.h ----
#import "NSObject+MachineTrap.h"
void machineTrap(void) { asm (" int3 "); } /// Program has TRAPPED to DEBUGGER ///`
(我选择 int3
而不是 BRK
、BKPT
、SVC
可能不正确。)
我在使用基于 ARM 的 MacBook Pro(Apple M1 芯片)时遇到了类似的问题。这对我有用:
asm ("brk #0xF000");
这也适用于 iOS 设备。