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
Is there a portable equivalent to DebugBreak()/__debugbreak?
提问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_BREAK
in 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_debugtrap
for 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.h
and- If
defined(SIGTRAP)
(i.e., POSIX),raise(SIGTRAP)
- Otherwise,
raise(SIGABRT)
- If
__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_trap
which 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 中的断点,以及用于在stepi或cont卡住的平台上扩展 GDB 的 Python 脚本。该脚本将debugbreak-step和debugbreak-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 继续,您可能无论如何都不想这样做。
回答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”指令)并生成异常时可以采取相应的行动。