#pragma once #include "tl/platform.h" #if defined(TL_FORCE_DEBUG) && defined(TL_RETAIL) # error "TL_FORCE_DEBUG and TL_RETAIL are incompatible!" #endif #if defined(TL_DEBUG) # error "Do not pass TL_DEBUG to the compiler. If you want to force debug, pass TL_FORCE_DEBUG" #endif #if !defined(NDEBUG) || defined(TL_FORCE_DEBUG) # define TL_DEBUG #endif #if defined(TL_PLATFORM_ANDROID_FAMILY) #if defined(TL_PLATFORM_ARCHITECTURE_AMD64) || defined(TL_PLATFORM_ARCHITECTURE_X86) extern __attribute__((gnu_inline, always_inline)) __inline__ void trap_instruction(void) noexcept { __asm__ volatile("int $0x03"); } #elif defined(TL_PLATFORM_ARCHITECTURE_ARM32) extern __attribute__((gnu_inline, always_inline)) __inline__ void trap_instruction(void) noexcept { /* See 'arm-linux-tdep.c' in GDB source, * 'eabi_linux_arm_le_breakpoint' */ __asm__ volatile(".inst 0xe7f001f0"); /* Has same known problem and workaround * as Thumb mode */ } #elif defined(TL_PLATFORM_ARCHITECTURE_ARM64) extern __attribute__((gnu_inline, always_inline)) __inline__ void trap_instruction(void) noexcept { /* See 'aarch64-tdep.c' in GDB source, * 'aarch64_default_breakpoint' */ __asm__ volatile(".inst 0xd4200000"); } #endif #endif #ifdef TL_DEBUG # if defined(TL_PLATFORM_WINDOWS_FAMILY) # define TL_BREAK() __debugbreak() //better than assert(0) as it will break on this exact line instead of deep in the assert function. # elif defined(TL_PLATFORM_OSX_FAMILY) || defined(TL_PLATFORM_LINUX_FAMILY) # include # define TL_BREAK() ::raise(SIGTRAP) # elif defined(TL_PLATFORM_ANDROID_FAMILY) # include # define TL_BREAK() ::raise(SIGSTOP) # endif #else # if defined(TL_PLATFORM_WINDOWS_FAMILY) # define TL_BREAK() do {} while (false) # else # define TL_BREAK() do {} while (false) # endif #endif