iOS上的可恢复断言/断点,如带MS编译器的__debugbreak()

我试图实现自定义资产macros(类似于什么assert.h),但我希望能够继续执行后,我得到和断言。

例如,一个这样的ASSERT实现可以是:

 #define ASSERT(expr) ((void)( (!!(expr)) || (__debugbreak(), 0))) 

__debugbreak是插入软件断点的Microsoft编译器中的一个内部函数,相当于x86中的_asm int 3 。 对于iOS有不同的方式来实现__debugbreak:

  • __asm__("int $3"); 为x86。
  • __asm__("bkpt #0"); 为了正常的arm。
  • __asm__("brk #0"); 为arm64
  • __builtin_trap ()
  • raise(SIGTRAP)

但是当我断言,我不能简单地继续下去,继续我在Visual Studio中工作的方式。 当在我的iOS构build断言它卡在断言,我别无select,但终止,我甚至不能手动移动指令指针,并跳过断言。

是否有可能在iOS上执行断言到debugging器的断言,并仍然允许我继续执行?

原来我可以通过一个系统调用来实现我想要的:

 #include <unistd.h> #if defined(__APPLE__) && defined(__aarch64__) #define __debugbreak() __asm__ __volatile__( \ " mov x0, %x0; \n" /* pid */ \ " mov x1, #0x11; \n" /* SIGSTOP */ \ " mov x16, #0x25; \n" /* syscall 37 = kill */ \ " svc #0x80 \n" /* software interrupt */ \ " mov x0, x0 \n" /* nop */ \ :: "r"(getpid()) \ : "x0", "x1", "x16", "memory") #elif defined(__APPLE__) && defined(__arm__) #define __debugbreak() __asm__ __volatile__( \ " mov r0, %0; \n" /* pid */ \ " mov r1, #0x11; \n" /* SIGSTOP */ \ " mov r12, #0x25; \n" /* syscall 37 = kill */ \ " svc #0x80 \n" /* software interrupt */ \ " mov r0, r0 \n" /* nop */ \ :: "r"(getpid()) \ : "r0", "r1", "r12", "memory") #elif defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__)) #define __debugbreak() __asm__ __volatile__("int $3; mov %eax, %eax") #endif #define MYASSERT(expr) do { if (!(expr)){ __debugbreak(); } } while(0) 

有一个尾随的NOP mov x0, x0是有原因的:当断言中断时,debugging器将在断言线路上停止,而不是一些随机的线路,下面的指令恰好位于这个线路上。

如果有人正在寻找相当于iOS上的IsDebuggerPresent ,可以使用AmibeingDebugged 。