在MSVC中, 调试中断() 或者 __debugbreak 导致调试器中断。在 x86 上它相当于编写“_asm int 3”,在 x64 上它是不同的。当使用 gcc (或任何其他标准编译器)编译时,我也想中断调试器。是否有独立于平台的功能或内在功能?我看到了 XCode问题 关于这一点,但它似乎不够便携。

边注:我主要想用它来实现 ASSERT,并且我知道我可以使用 assert() 来实现这一点,但我也想在代码中写入 DEBUG_BREAK 或其他内容。

有帮助吗?

解决方案

如何基于#ifdef定义基于当前体系结构或平台扩展到不同构造的条件宏。

类似的东西:

#ifdef _MSC_VER
#define DEBUG_BREAK __debugbreak()
#else
...
#endif

这将由预处理器根据编译代码的平台扩展正确的调试器中断指令。这样,您始终可以在代码中使用 DEBUG_BREAK

其他提示

可移植到大多数POSIX系统的方法是:

raise(SIGTRAP);

GCC有一个名为 __ builtin_trap 的内置函数,你可以看到这里,但是假设代码执行一旦达到就停止。

确保 __ builtin_trap()调用是有条件的,否则后面不会发出代码。

这篇文章是在YMMV的所有5分钟测试的推动下推动的。

这看起来像是一个合适的compat库 https://github.com/scottt/debugbreak

我刚刚添加了 一个模块可移植片段 (可移植代码的公共领域片段的集合)来执行此操作。它不是 100% 可移植的,但它应该非常强大:

  • __builtin_debugtrap 对于某些版本的 clang(标识为 __has_builtin(__builtin_debugtrap))
  • 在 MSVC 和英特尔 C/C++ 编译器上: __debugbreak
  • 对于 ARM C/C++ 编译器: __breakpoint(42)
  • 对于 x86/x86_64,汇编: int $03
  • 对于 ARM Thumb,汇编: .inst 0xde01
  • 对于 ARM AArch64,汇编: .inst 0xd4200000
  • 对于其他ARM,汇编: .inst 0xe7f001f0
  • 对于阿尔法,组装: bpt
  • 对于带有 GCC 的非托管 C(或伪装成 GCC 的东西), __builtin_trap
  • 否则,包括 signal.h
    • 如果 defined(SIGTRAP) (即 POSIX), raise(SIGTRAP)
    • 否则, raise(SIGABRT)

将来,可移植片段中的模块可能会扩展以包含其他逻辑,我可能会忘记更新此答案,因此您应该在那里查找更新。它是公共领域 (CC0),因此请随意窃取代码。

如果你认为assert(x)足够便携,那么assert(false)似乎是你问题的明显可移植解决方案。

如果您正在尝试调试与崩溃相关的条件,那么老式的abort()将在大多数平台上为您提供调用堆栈。缺点是您不能继续使用当前的PC,您可能不想这样做。

http://www.cplusplus.com/reference/cstdlib/abort/

不使用“普通”调试中断,为什么不使用以下之一,例如除以零:

int iCrash = 13 / 0;

或取消引用NULL指针:

BYTE bCrash = *(BYTE *)(NULL);

至少这可以在许多平台/架构中移植。

在许多调试器中,您可以指定要对哪些异常执行的操作,以便在执行上述某个操作时(例如暂停执行,ala和“int 3”指令)并生成异常时,您可以采取相应的操作。

#define __debugbreak() \
do \
{       static bool b; \
        while (!b) \
                sleep(1); \
        b = false; \
} while (false)

当进程处于休眠状态时,您可以将调试器附加到进程,更改变量b以打破循环并执行您的操作。此代码可能无法在优化的构建中使用!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top