使用 MS 编译器可在 iOS 上恢复 assert/breakpoint,如 __debugbreak()
Resumable assert/breakpoint on iOS like __debugbreak() with MS compiler
我正在尝试实现自定义资产宏(类似于 assert.h 拥有的),但我希望能够在获取并断言后继续执行。
例如,一个这样的 ASSERT
实现可以是:
#define ASSERT(expr) ((void)( (!!(expr)) || (__debugbreak(), 0)))
__debugbreak是微软编译器中插入软件断点的内在函数,相当于x86中的_asm int 3
。对于 iOS 有不同的方法来实现 __debugbreak:
__asm__("int ");
x86。
__asm__("bkpt #0");
常规手臂。
__asm__("brk #0");
for arm64
- __builtin_trap()
raise(SIGTRAP)
但是当我的断言命中时,对于所有这些,我不能简单地跨过并继续我在使用 visual studio 时可以做的方式;当在我的 iOS 构建中断言时,它卡在断言处,我别无选择,只能终止,我什至无法手动移动指令指针并跳过断言。
是否可以在 iOS 上实施断言,它会进入调试器并仍然允许我继续执行?
原来我可以通过系统调用实现我想要的:
#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 ; mov %eax, %eax")
#endif
#define MYASSERT(expr) do { if (!(expr)){ __debugbreak(); } } while(0)
有一个尾随的 NOP mov x0, x0
是有原因的:当断言中断时,调试器将准确地停在断言行,而不是以下指令恰好所在的随机行。
以防有人正在寻找 IsDebuggerPresent on iOS, you can use AmIBeingDebugged.
的等价物
我正在尝试实现自定义资产宏(类似于 assert.h 拥有的),但我希望能够在获取并断言后继续执行。
例如,一个这样的 ASSERT
实现可以是:
#define ASSERT(expr) ((void)( (!!(expr)) || (__debugbreak(), 0)))
__debugbreak是微软编译器中插入软件断点的内在函数,相当于x86中的_asm int 3
。对于 iOS 有不同的方法来实现 __debugbreak:
__asm__("int ");
x86。__asm__("bkpt #0");
常规手臂。__asm__("brk #0");
for arm64- __builtin_trap()
raise(SIGTRAP)
但是当我的断言命中时,对于所有这些,我不能简单地跨过并继续我在使用 visual studio 时可以做的方式;当在我的 iOS 构建中断言时,它卡在断言处,我别无选择,只能终止,我什至无法手动移动指令指针并跳过断言。
是否可以在 iOS 上实施断言,它会进入调试器并仍然允许我继续执行?
原来我可以通过系统调用实现我想要的:
#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 ; mov %eax, %eax")
#endif
#define MYASSERT(expr) do { if (!(expr)){ __debugbreak(); } } while(0)
有一个尾随的 NOP mov x0, x0
是有原因的:当断言中断时,调试器将准确地停在断言行,而不是以下指令恰好所在的随机行。
以防有人正在寻找 IsDebuggerPresent on iOS, you can use AmIBeingDebugged.
的等价物