Is there a portable equivalent to DebugBreak()/__debugbreak?
What about defining a conditional macro based on #ifdef that expands to different constructs based on the current architecture or platform.
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.
Xcode equivalent of ' __asm int 3 / DebugBreak() / Halt?
http://developer.apple.com/documentation/DeveloperTools/Conceptual/XcodeProjectManagement/090_Running_Programs/chapter_11_section_3.html
asm {trap} ; Halts a program running on PPC32 or PPC64.
__asm {int 3} ; Halts a program running on IA-32.
__debugbreak and int3 instruction
int3
is a single-byte instruction (and so is the push
in this case). call
isn't. You jmp
will jump into the "middle" of call
if you overwrite your push
with call
instead of int3
.
But unless there's a way to reach the push
(I see no label before it to jump/call to), putting a breakpoint on push
is useless, isn't it?
Resumable assert/breakpoint on iOS like __debugbreak() with MS compiler
Turns out I can achieve what I want by making a syscall:
#include <unistd.h>
#if defined(__APPLE__) && defined(__aarch64__)
#define __debugbreak() __asm__ __volatile__( \
" mov x0, %x0; \n" /* pid */ \
" mov x1, #0x11; \n" /* SIGSTOP */ \
" mov x16, #0x25; \n" /* syscall 37 = kill */ \
" svc #0x80 \n" /* software interrupt */ \
" mov x0, x0 \n" /* nop */ \
:: "r"(getpid()) \
: "x0", "x1", "x16", "memory")
#elif defined(__APPLE__) && defined(__arm__)
#define __debugbreak() __asm__ __volatile__( \
" mov r0, %0; \n" /* pid */ \
" mov r1, #0x11; \n" /* SIGSTOP */ \
" mov r12, #0x25; \n" /* syscall 37 = kill */ \
" svc #0x80 \n" /* software interrupt */ \
" mov r0, r0 \n" /* nop */ \
:: "r"(getpid()) \
: "r0", "r1", "r12", "memory")
#elif defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__))
#define __debugbreak() __asm__ __volatile__("int $3; mov %eax, %eax")
#endif
#define MYASSERT(expr) do { if (!(expr)){ __debugbreak(); } } while(0)
There is a trailing NOP mov x0, x0
for a reason: when assert breaks, debugger will stop exactly at the assert line and not some random line where the following instruction happens to be located.
In case if somebody is looking for equivalent of IsDebuggerPresent on iOS, you can use AmIBeingDebugged.
What is the difference between int3 instruction and call __debugbreak?
int3
is an x86 instruction.
__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
Related Topics
Thread Safe Implementation of Circular Buffer
Convert String to Mathematical Evaluation
What Is the Fastest Way to Change a Key of an Element Inside Std::Map
Get the Status of a Std::Future
Std::Shared_Ptr Initialization: Make_Shared<Foo>() VS Shared_Ptr<T>(New Foo)
Accessing Protected Members of Superclass in C++ with Templates
Best Method for Storing This Pointer for Use in Wndproc
What Destructors Are Run When the Constructor Throws an Exception
Converting Data from Glreadpixels() to Opencv::Mat
How to Convert Unsigned Char* to Std::String in C++
What Is the Meaning of Clang's -Wweak-Vtables
C++ Socket Server - Unable to Saturate Cpu
Can Openssl on Windows Use the System Certificate Store
How Does Openmp Handle Nested Loops
How to Change the Variable to Which a C++ Reference Refers