C++ 使用MS编译器在iOS上可恢复的断言/断点,如_debugbreak()
我正在尝试实现自定义资产宏(类似于assert.h所做的),但我希望能够在获取和断言后继续执行 例如,一个这样的C++ 使用MS编译器在iOS上可恢复的断言/断点,如_debugbreak(),c++,ios,c,debugging,assert,C++,Ios,C,Debugging,Assert,我正在尝试实现自定义资产宏(类似于assert.h所做的),但我希望能够在获取和断言后继续执行 例如,一个这样的ASSERT实现可以是: #define ASSERT(expr) ((void)( (!!(expr)) || (__debugbreak(), 0))) 是Microsoft编译器中插入软件断点的固有函数,相当于x86中的\u asm int 3。对于iOS,有不同的方法来实现此功能: \uuuu asm\uuuuuuuuuuuuuuuuu(“int$3”)用于x86 uuu
ASSERT
实现可以是:
#define ASSERT(expr) ((void)( (!!(expr)) || (__debugbreak(), 0)))
是Microsoft编译器中插入软件断点的固有函数,相当于x86中的\u asm int 3
。对于iOS,有不同的方法来实现此功能:
\uuuu asm\uuuuuuuuuuuuuuuuu(“int$3”)代码>用于x86
uuu asm_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu代码>用于常规手臂
uuu asm_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu代码>用于arm64
- ()
rise(SIGTRAP)
是否可以在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 $3; mov %eax, %eax")
#endif
#define MYASSERT(expr) do { if (!(expr)){ __debugbreak(); } } while(0)
#包括
#如果已定义(uuu苹果公司)和已定义(uuu aarch64)
#定义_debugbreak()_asm__ _volatile__(\
“mov x0,%x0;\n”/*pid*/\
“mov x1,#0x11;\n”/*SIGSTOP*/\
“mov x16,#0x25;\n”/*syscall 37=kill*/\
“svc#0x80\n”/*软件中断*/\
“mov x0,x0\n”/*nop*/\
:“r”(getpid())\
:“x0”、“x1”、“x16”、“内存”)
#elif已定义(uuu苹果公司)&已定义(uuu手臂)
#定义_debugbreak()_asm__ _volatile__(\
“mov r0,%0;\n”/*pid*/\
“mov r1,#0x11;\n”/*SIGSTOP*/\
“mov r12,#0x25;\n”/*syscall 37=kill*/\
“svc#0x80\n”/*软件中断*/\
“mov r0,r0\n”/*nop*/\
:“r”(getpid())\
:“r0”、“r1”、“r12”、“内存”)
#elif已定义(uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
#定义调试中断()
#恩迪夫
#定义MYASSERT(expr)do{if(!(expr)){{uuu debugbreak();}}}while(0)
后面有一个NOPmov x0,x0
,原因是:当断言中断时,调试器将恰好在断言行停止,而不是在以下指令恰好位于的某个随机行停止
如果有人在iOS上寻找等价物,您可以使用。\u asm\u(“int$3”);适合me@Spads
int$3
在模拟器中工作只是因为它是x86,而不是arm.Fair point。没有在iPhone上检查它。@Spads在模拟器中打开int 3
后,你能继续调试吗?是的,这对MEA有效。据我所知,这遗漏了一些重要的东西:要进行的系统调用需要在调用svc#0x80
之前进入r12
(这是最重要的)。因此,似乎纯粹是出于偶然,您在r12
中得到了一个对您有用的值,可能是ptrace
。我建议您在工作版本中查看r12
。是的,我认为您是对的,我在AmIBeingDebugged线程中的注释无效。我认为,只要检查活动程序集,甚至不检查需要什么参数,就可以实现svc#80
。对于模拟器,还需要检查x86_64。