在Mac OS X和iOS模拟器(均为x86)中,我们可以使用内联汇编中的int3
指令陷阱到调试器(LLDB)。这很好,因为它陷阱到特定的代码行,但我们可以通过在调试器中按下continue来立即继续。
有没有办法在iOS硬件上执行此操作?
An answer to an older question提到raise(SIGINT)
,据我所知(从检查signal.h
)不存在。另一个答案提到了trap
汇编指令,它会导致构建错误(“无法识别的指令助记符”)。同样未被认识的是BKPT
汇编指令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
包括XNU的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上发出“无法识别的指令助记符”,类似于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
可能不正确。)