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

Pav*_*l P 10 c c++ debugging assert ios

我正在尝试实现自定义资产宏(类似于assert.h所具有的),但我希望能够在获得并断言之后继续执行.

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

#define ASSERT(expr) ((void)( (!!(expr)) || (__debugbreak(), 0)))
Run Code Online (Sandbox Code Playgroud)

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

  • __asm__("int $3"); 对于x86.
  • __asm__("bkpt #0"); 对于常规手臂.
  • __asm__("brk #0"); for arm64
  • __builtin_trap()
  • raise(SIGTRAP)

但是当我的断言命中时,所有这些都不能简单地跨过并继续我在使用visual studio时可以做的事情; 当我的iOS构建中的某些东西断言它在断言时卡住了,我别无选择,只能终止,我甚至无法手动移动指令指针并跳过断言.

是否有可能在iOS上实现断言进入调试器并仍允许我继续执行的断言?

Pav*_*l P 8

事实证明,通过建立一个系统调用,我可以实现我想要的目标:

#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)
Run Code Online (Sandbox Code Playgroud)

有一个尾随的NOP mov x0, x0是有原因的:当断言中断时,调试器将完全停在断言线而不是某个随机行,而后面的指令恰好位于其中.

如果有人在iOS上寻找等效的IsDebuggerPresent,您可以使用AmIBeingDebugged.