Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

In MSVC, DebugBreak() or __debugbreak cause 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 question about that, but it doesn't seem portable enough.

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.

like image 361
vividos Avatar asked Oct 06 '08 08:10

vividos


4 Answers

A method that is portable to most POSIX systems is:

raise(SIGTRAP);
like image 182
caf Avatar answered Nov 01 '22 14:11

caf


I just added a module to 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:

  • __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: int3
  • 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.

like image 34
nemequ Avatar answered Nov 01 '22 16:11

nemequ


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.

like image 19
Jorge Ferreira Avatar answered Nov 01 '22 15:11

Jorge Ferreira


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.

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

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

like image 15
Hasturkun Avatar answered Nov 01 '22 15:11

Hasturkun