1 /* 2 * Created by Phil on 21/08/2014 3 * Copyright 2014 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_FATAL_CONDITION_H_INCLUDED 10 #define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED 11 12 #include "catch_platform.h" 13 #include "catch_compiler_capabilities.h" 14 15 #include <cassert> 16 17 namespace Catch { 18 19 // Wrapper for platform-specific fatal error (signals/SEH) handlers 20 // 21 // Tries to be cooperative with other handlers, and not step over 22 // other handlers. This means that unknown structured exceptions 23 // are passed on, previous signal handlers are called, and so on. 24 // 25 // Can only be instantiated once, and assumes that once a signal 26 // is caught, the binary will end up terminating. Thus, there 27 class FatalConditionHandler { 28 bool m_started = false; 29 30 // Install/disengage implementation for specific platform. 31 // Should be if-defed to work on current platform, can assume 32 // engage-disengage 1:1 pairing. 33 void engage_platform(); 34 void disengage_platform(); 35 public: 36 // Should also have platform-specific implementations as needed 37 FatalConditionHandler(); 38 ~FatalConditionHandler(); 39 engage()40 void engage() { 41 assert(!m_started && "Handler cannot be installed twice."); 42 m_started = true; 43 engage_platform(); 44 } 45 disengage()46 void disengage() { 47 assert(m_started && "Handler cannot be uninstalled without being installed first"); 48 m_started = false; 49 disengage_platform(); 50 } 51 }; 52 53 //! Simple RAII guard for (dis)engaging the FatalConditionHandler 54 class FatalConditionHandlerGuard { 55 FatalConditionHandler* m_handler; 56 public: FatalConditionHandlerGuard(FatalConditionHandler * handler)57 FatalConditionHandlerGuard(FatalConditionHandler* handler): 58 m_handler(handler) { 59 m_handler->engage(); 60 } ~FatalConditionHandlerGuard()61 ~FatalConditionHandlerGuard() { 62 m_handler->disengage(); 63 } 64 }; 65 66 } // end namespace Catch 67 68 #endif // TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED 69