What is __debugbreak? Is it used for triggering SIGTRAP? What is the difference between int3 and __debugbreak?
-
1On the platforms that I am familiar with, the two map to the same thing. – 500 - Internal Server Error Feb 05 '19 at 17:39
1 Answers
__debugbreak()
is an intrinsic supported by MSVC that will get the compiler to emit that instruction when compiling for x86, or whatever software-breakpoint instruction is appropriate for the target ISA (e.g. ARM, AArch64, etc.)
ICC also supports it, but other compilers (like gcc) don't..
You wouldn't do call __debugbreak
in asm, you'd just write int3
. e.g. if you compile a function that uses it, like
void foo() {
__debugbreak();
}
MSVC on the Godbolt compiler explorer produces this asm:
void foo(void) PROC ; foo
npad 2
int 3
ret 0
Notice the lack of a call
instruction anywhere. It's an intrinsic that "inlines" even with optimization disabled. It's not "just" a function.
This is the same as how _mm_mfence()
is an intrinsic for the mfence
instruction, or _mm_popcnt_u64
for 64-bit operand-size popcnt
.
Related: Is there a portable equivalent to DebugBreak()/__debugbreak?
says clang has a __builtin_debugtrap()
.
Another answer there says the more widely available GNU C __builtin_trap()
is assumed to stop / abort the program, not act like a breakpoint. (So gcc won't emit any code after an unconditional __builtin_trap
.)
update: apparently MSVC does let you take its address, so I guess there is a library version of it somewhere. So you could write call __debugbreak
in asm, but you still wouldn't because it's pointless.
GCC does not let you take the address of builtins, for example trying to compile:
int (*getbuiltin(void))(unsigned) { return &__builtin_popcount; }
gives you this error:
error: built-in function '__builtin_popcount' must be directly called
But MSVC and ICC compile void (*getFunc(void))(void) { return &__debugbreak; }
into this (on Godbolt)
void (__cdecl*getFunc(void))(void) PROC ; getFunc
lea rax, OFFSET FLAT:__debugbreak
ret 0

- 328,167
- 45
- 605
- 847
-
__debugbreak is a function. Can you elaborate on why can't we call this in asm? – anandthegreat Feb 06 '19 at 09:19
-
1@anandthegreat: Updated. It's not *just* a function, there's never a reason not to inline it as `int3` in asm, unless you're taking the address as a function pointer. I'm surprised MSVC even has a non-inline version of it in the library. GCC doesn't let you take the address of built-in functions. – Peter Cordes Feb 06 '19 at 10:04
-
@PeterCordes ["Some intrinsics are available only as intrinsics, and some are available both in function and intrinsic implementations."](https://docs.microsoft.com/en-us/cpp/intrinsics/compiler-intrinsics?view=vs-2019) However, ["This routine is only available as an intrinsic."](https://docs.microsoft.com/en-us/cpp/intrinsics/debugbreak?view=vs-2019) (and even as far back as VS2015), so IDK. That being said, there is the [`DebugBreak()` Windows API call](https://msdn.microsoft.com/library/windows/desktop/ms679297.aspx) in `kernel32.dll`, so it's possible there's a stub somewhere in the vcrt… – andlabs May 13 '19 at 03:49