C++ 是否有可移植的等价于 DebugBreak()/__debugbreak?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/173618/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:26:34  来源:igfitidea点击:

Is there a portable equivalent to DebugBreak()/__debugbreak?

c++portabilitydebugbreak

提问by vividos

In MSVC, DebugBreak()or __debugbreakcause a debugger to break. On x86 it is equivalent to writing "_asm int 3", on x64 it is something different. When compiling with gcc (or any other standard compiler) I want to do a break into debugger, too. Is there a platform independent function or intrinsic? I saw the XCode questionabout that, but it doesn't seem portable enough.

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

Sidenote: I mainly want to implement ASSERT with that, and I understand I can use assert() for that, but I also want to write DEBUG_BREAK or something into the code.

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

采纳答案by Jorge Ferreira

What about defining a conditional macro based on #ifdef that expands to different constructs based on the current architecture or platform.

如何定义基于 #ifdef 的条件宏,该宏根据当前架构或平台扩展到不同的结构。

Something like:

就像是:

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

This would be expanded by the preprocessor the correct debugger break instruction based on the platform where the code is compiled. This way you always use DEBUG_BREAKin your code.

这将由预处理器根据编译代码的平台扩展正确的调试器中断指令。这样你总是DEBUG_BREAK在你的代码中使用。

回答by caf

A method that is portable to most POSIX systems is:

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

raise(SIGTRAP);

回答by nemequ

I just added a moduleto portable-snippets(a collection of public domain snippets of portable code) to do this. It's not 100% portable, but it should be pretty robust:

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

  • __builtin_debugtrapfor some versions of clang (identified with __has_builtin(__builtin_debugtrap))
  • On MSVC and Intel C/C++ Compiler: __debugbreak
  • For ARM C/C++ Compiler: __breakpoint(42)
  • For x86/x86_64, assembly: 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.hand
    • If defined(SIGTRAP)(i.e., POSIX), raise(SIGTRAP)
    • Otherwise, raise(SIGABRT)
  • __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
  • 对于 Alpha,组装: bpt
  • 对于带有 GCC(或伪装成它的东西)的非托管 C, __builtin_trap
  • 否则,包括signal.h
    • 如果defined(SIGTRAP)(即POSIX),raise(SIGTRAP)
    • 除此以外, 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.

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

回答by Hasturkun

GCC has a builtin function named __builtin_trapwhich you can see here, however it is assumed that code execution halts once this is reached.

GCC 有一个名为的内置函数__builtin_trap,您可以在此处看到,但是假设一旦达到该函数,代码执行就会停止。

you shouldensure that the __builtin_trap()call is conditional, otherwise no code will be emitted after it.

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

this post fueled by all of 5 minutes of testing, YMMV.

这篇文章由所有 5 分钟的测试推动,YMMV。

回答by pixelbeat

This looks like an appropriate compat library https://github.com/scottt/debugbreak

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

回答by Suma

If you consider assert(x)portable enough, assert(false)seems to be the obvious portable solution to your problem.

如果您认为assert(x)足够便携,这assert(false)似乎是解决您问题的明显便携解决方案。

回答by QwazyWabbit

This seems to be a very good, portable solution to this question: https://github.com/scottt/debugbreak

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

The header provided in the repository cited (debugbreak.h) encapsulates MSVC's

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

    __debugbreak, 

and

    __asm__ volatile("int 
    __asm__ volatile(".inst 0xe7f001f0");
x03");

on i386 and x86_64, and on ARM it implements

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

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

as well as documenting some workarounds for problems noted in the header for single-stepping past the breakpoint in GDB plus a Python script for extending GDB on those platforms where stepior contget stuck. The script adds debugbreak-stepand debugbreak-continueto GDB.

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

回答by johnwbyrd

If you are trying to debug a crash-related condition, good old fashioned abort() will give you a call stack on most platforms. Downside is that you can't continue from the current PC, which you probably don't want to do anyway.

如果您正在尝试调试与崩溃相关的情况,好的老式 abort() 将在大多数平台上为您提供调用堆栈。缺点是您无法从当前的 PC 继续,您可能无论如何都不想这样做。

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

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

回答by johnwbyrd

int iCrash = 13 / 0;

When the process is sleeping, you can attach a debugger to the process, change the variable b to break the loop and do your thing. This code might not work in an optimized build!

当进程休眠时,您可以将调试器附加到进程,更改变量 b 以中断循环并执行您的操作。此代码在优化构建中可能不起作用!

回答by QAZ

Instead of using 'normal' debug breaks, why not use one of the following, like a divide by zero:

与其使用“正常”调试中断,不如使用以下方法之一,例如除以零:

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

or dereference a NULL pointer:

或取消引用 NULL 指针:

##代码##

At least this is portable accross many platforms/architectures.

至少这是跨许多平台/架构的可移植性。

In many debuggers you can specify what action you want to perform on what exceptions so you can act accordingly when one of the above is hit (like pause execution, ala an "int 3" instruction) and an exception is generated.

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