Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/105.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用MS编译器在iOS上可恢复的断言/断点,如_debugbreak()_C++_Ios_C_Debugging_Assert - Fatal编程技术网

C++ 使用MS编译器在iOS上可恢复的断言/断点,如_debugbreak()

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.h所做的),但我希望能够在获取和断言后继续执行

例如,一个这样的
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)
但是,当我的断言成功时,我不能简单地跨过去继续使用VisualStudio的工作方式;当我的iOS中的某个assert构建时,它会卡在assert上,我别无选择,只能终止,我甚至无法手动移动指令指针并跳过assert


是否可以在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)
后面有一个NOP
mov 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。