1 /* 2 * Created by Phil on 3/12/2013. 3 * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. 4 * 5 * Distributed under the Boost Software License, Version 1.0. (See accompanying 6 * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 * 8 */ 9 #ifndef TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED 10 #define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED 11 12 #include "catch_platform.h" 13 14 #include <string> 15 16 namespace Catch{ 17 18 bool isDebuggerActive(); 19 void writeToDebugConsole( std::string const& text ); 20 } 21 22 #ifdef CATCH_PLATFORM_MAC 23 24 // The following code snippet based on: 25 // http://cocoawithlove.com/2008/03/break-into-debugger.html 26 #if defined(__ppc64__) || defined(__ppc__) 27 #define CATCH_TRAP() \ 28 __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \ 29 : : : "memory","r0","r3","r4" ) /* NOLINT */ 30 #elif defined(__i386__) || defined(__x86_64__) 31 #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */ 32 #elif defined(__aarch64__) 33 #define CATCH_TRAP() __asm__(".inst 0xd4200000") 34 #endif 35 36 #elif defined(CATCH_PLATFORM_LINUX) 37 // If we can use inline assembler, do it because this allows us to break 38 // directly at the location of the failing check instead of breaking inside 39 // raise() called from it, i.e. one stack frame below. 40 #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64)) 41 #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */ 42 #else // Fall back to the generic way. 43 #include <signal.h> 44 45 #define CATCH_TRAP() raise(SIGTRAP) 46 #endif 47 #elif defined(_MSC_VER) 48 #define CATCH_TRAP() __debugbreak() 49 #elif defined(__MINGW32__) 50 extern "C" __declspec(dllimport) void __stdcall DebugBreak(); 51 #define CATCH_TRAP() DebugBreak() 52 #endif 53 54 #ifdef CATCH_TRAP 55 #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } 56 #else 57 #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue(); 58 #endif 59 60 #endif // TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED 61