是否有一个可移植的等效于DebugBreak()/ __ debugbreak?

viv*_*dos 51 c++ portability debugbreak

在MSVC中,DebugBreak()__debugbreak导致调试器中断.在x86上它相当于写"_asm int 3",在x64上它是不同的东西.在使用gcc(或任何其他标准编译器)进行编译时,我也想进入调试器.是否存在平台无关功能或内在功能?我看到了XCode的问题,但它似乎不够便携.

旁注:我主要想用它来实现ASSERT,我知道我可以使用assert(),但我也想在代码中编写DEBUG_BREAK或其他东西.

caf*_*caf 40

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

raise(SIGTRAP);
Run Code Online (Sandbox Code Playgroud)

  • `raise(SIGTRAP)`在gcc/Linux上对我很有用.`__builtin_trap()`导致`SIGILL`信号被引发. (5认同)
  • @thomthom:你有#include <signal.h>`? (4认同)

Jor*_*ira 14

如何基于#ifdef定义一个基于当前架构或平台扩展到不同构造的条件宏.

就像是:

#ifdef _MSC_VER
#define DEBUG_BREAK __debugbreak()
#else
...
#endif
Run Code Online (Sandbox Code Playgroud)

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


Has*_*kun 12

GCC有一个内置函数__builtin_trap,你可以在这里看到,但是假设代码执行一旦达到就停止了.

应该确保__builtin_trap()调用是有条件的,否则之后就不会发出代码.

这篇文章由YMMV进行了5分钟的测试.

  • `__builtin_trap` 通常编译为 `ud2` (x86) 或其他非法指令,而不是调试断点,并且也被视为 noreturn,即使使用调试器,您也无法继续执行。 (5认同)

nem*_*equ 10

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

  • __builtin_debugtrap对于某些版本的clang(以标识__has_builtin(__builtin_debugtrap)
  • 在MSVC和Intel C / C ++编译器上: __debugbreak
  • 对于ARM C / C ++编译器: __breakpoint(42)
  • 对于x86 / x86_64,组装: int $03
  • For ARM Thumb, assembly: .inst 0xde01
  • For ARM AArch64, assembly: .inst 0xd4200000
  • For other ARM, assembly: .inst 0xe7f001f0
  • For Alpha, assembly: bpt
  • For non-hosted C with GCC (or something which masquerades as it), __builtin_trap
  • Otherwise, include signal.h and
    • If defined(SIGTRAP) (i.e., POSIX), raise(SIGTRAP)
    • Otherwise, raise(SIGABRT)

In the future the module in portable-snippets may expand to include other logic and I'll probably forget to update this answer, so you should look there for updates. It's public domain (CC0), so feel free to steal the code.

  • 对于 x86(包括 x86-64)GAS 语法,最好编写 `int3` 来明确您想要特殊情况的调试中断指令,一个字节 `CC` 而不是 `CD 03`,在极少数情况下,问题(代码大小和 v8086 模式)。(https://www.felixcloutier.com/x86/intn:into:int3:int1)。对于 NASM,它们实际上以不同的方式组装,GAS 将两者优化为“int3”。 (2认同)
  • `__builtin_trap` 通常编译为 `ud2` (x86) 或其他非法指令,而不是调试断点,并且也被视为 noreturn,即使使用调试器,您也无法继续执行。它不属于这个列表。例如,在一个简单函数中,在 C“return x”语句之前使用“ud2”之后,没有“ret”指令。 (2认同)

pix*_*eat 9

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


Qwa*_*bit 6

这似乎是这个问题的一个非常好的、可移植的解决方案: https: //github.com/scottt/debugbreak

引用的存储库 (debugbreak.h) 中提供的标头封装了 MSVC

    __debugbreak, 
Run Code Online (Sandbox Code Playgroud)

    __asm__ volatile("int $0x03");
Run Code Online (Sandbox Code Playgroud)

在 i386 和 x86_64 上,以及在 ARM 上它实现

    __asm__ volatile(".inst 0xe7f001f0");
Run Code Online (Sandbox Code Playgroud)

以及记录标题中指出的问题的一些解决方法,用于单步执行 GDB 中的断点,以及用于在stepicont遇到问题的平台上扩展 GDB 的 Python 脚本。该脚本将debugbreak-stepdebugbreak-continue添加到 GDB。