iOS上的可恢复断言/断点,如带有MS编译器的__debugbreak() [英] Resumable assert/breakpoint on iOS like __debugbreak() with MS compiler

查看:246
本文介绍了iOS上的可恢复断言/断点,如带有MS编译器的__debugbreak()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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

 # define ASSERT(expr)((void)((!!(expr))||(__ decugug(),0)))

__debugbreak 是Microsoft编译器中的内在功能插入软件断点,相当于x86中的 _asm int 3 。对于iOS,有不同的方法来实现__debugbreak:




  • __ asm __(int $ 3); for x86。

  • __ asm __(bkpt#0); 常规手臂。

  • __ asm __(brk#0); for arm64

  • __ builtin_trap ()

  • raise(SIGTRAP )



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



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

解决方案

原来我可以通过建立系统调用实现我想要的目标:

  #include< unistd.h> 

#if定义(__ APPLE__)&&已定义(__ 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/ *软件中断* / \
mov x0,x0 \ n/ * nop * / \
::r(getpid())\
:x0 ,x1,x16,记忆)
#elif定义(__ APPLE__)&&已定义(__ 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/ *软件中断* / \
mov r0,r0 \ n/ * nop * / \
::r(getpid())\
:r0 ,r1,r12,记忆)
#elif定义(__ APPLE__)&& (已定义(__ i386__)||已定义(__ x86_64__))
#define __debugbreak()__ asm__ __volatile __(int $ 3; mov%eax,%eax)
#endif

#define MYASSERT(expr)do {if(!(expr)){__ decugbreak(); while(0)

有一个尾随NOP mov x0,x0 原因是:当断言中断时,调试器将完全停在断言行,而不是一些随机行,其中恰好找到了以下指令。



<如果有人正在寻找相当于 IsDebuggerPresent ,您可以使用 AmIBeingDebugged


I'm trying to implement custom asset macro (similar to what assert.h has), but I want to be able to continue execution after I get and assert.

For example, one such ASSERT implementation could be:

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

__debugbreak is an intrinsic function in Microsoft compilers that inserts software breakpoint, equivalent to _asm int 3 in x86. for iOS there are different ways to implement that __debugbreak:

  • __asm__("int $3"); for x86.
  • __asm__("bkpt #0"); for regular arm.
  • __asm__("brk #0"); for arm64
  • __builtin_trap()
  • raise(SIGTRAP)

but with all of them when my assert hits I cannot simply step over and continue the way I can do when working with visual studio; when something assert in my iOS builds it gets stuck at the assert and I have no choice but to terminate, I cannot even move instruction pointer manually and skip the assert.

Is it possible to implement asserts on iOS that would break into debugger and would still allow me to continue execution?

解决方案

Turns out I can achieve what I want by making a syscall:

#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)

There is a trailing NOP mov x0, x0 for a reason: when assert breaks, debugger will stop exactly at the assert line and not some random line where the following instruction happens to be located.

In case if somebody is looking for equivalent of IsDebuggerPresent on iOS, you can use AmIBeingDebugged.

这篇关于iOS上的可恢复断言/断点,如带有MS编译器的__debugbreak()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆