catch_fatal_condition.h 2.2 KB

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