gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 03:09:48 25 4
gpt4 key购买 nike

我正在尝试实现自定义 Assets 宏(类似于 assert.h 的内容),但我希望能够在获取并断言后继续执行。

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

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

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

  • __asm__("int $3"); 用于 x86。
  • __asm__("bkpt #0"); 用于常规 ARM 。
  • __asm__("brk #0"); for arm64
  • __builtin_trap ()
  • 提高(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 $3; mov %eax, %eax")
#endif

#define MYASSERT(expr) do { if (!(expr)){ __debugbreak(); } } while(0)

有一个尾随 NOP mov x0, x0 的原因是:当断言中断时,调试器将准确地停在断言行,而不是后续指令恰好所在的随机行。

以防有人正在寻找 IsDebuggerPresent 的等价物在 iOS 上,您可以使用 AmIBeingDebugged .

关于c++ - iOS 上的可恢复断言/断点,例如带有 MS 编译器的 __debugbreak(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44140778/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com