SignalHandler.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. //
  2. // SignalHandler.h
  3. //
  4. // $Id: //poco/1.3/Foundation/include/Poco/SignalHandler.h#2 $
  5. //
  6. // Library: Foundation
  7. // Package: Threading
  8. // Module: SignalHandler
  9. //
  10. // Definition of the SignalHandler class.
  11. //
  12. // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
  13. // and Contributors.
  14. //
  15. // Permission is hereby granted, free of charge, to any person or organization
  16. // obtaining a copy of the software and accompanying documentation covered by
  17. // this license (the "Software") to use, reproduce, display, distribute,
  18. // execute, and transmit the Software, and to prepare derivative works of the
  19. // Software, and to permit third-parties to whom the Software is furnished to
  20. // do so, all subject to the following:
  21. //
  22. // The copyright notices in the Software and this entire statement, including
  23. // the above license grant, this restriction and the following disclaimer,
  24. // must be included in all copies of the Software, in whole or in part, and
  25. // all derivative works of the Software, unless such copies or derivative
  26. // works are solely in the form of machine-executable object code generated by
  27. // a source language processor.
  28. //
  29. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  30. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  31. // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
  32. // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
  33. // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
  34. // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  35. // DEALINGS IN THE SOFTWARE.
  36. //
  37. #ifndef Foundation_SignalHandler_INCLUDED
  38. #define Foundation_SignalHandler_INCLUDED
  39. #include "Poco/Foundation.h"
  40. #if defined(POCO_OS_FAMILY_UNIX)
  41. #include <vector>
  42. #include <setjmp.h>
  43. namespace Poco {
  44. class Foundation_API SignalHandler
  45. /// This helper class simplifies the handling of POSIX signals.
  46. ///
  47. /// The class provides a signal handler (installed with
  48. /// installHandlers()) that translates certain POSIX
  49. /// signals (SIGILL, SIGBUS, SIGSEGV, SIGSYS) into
  50. /// C++ exceptions.
  51. ///
  52. /// Internally, a stack of sigjmp_buf structs is maintained for
  53. /// each thread. The constructor pushes a new sigjmp_buf onto
  54. /// the current thread's stack. The destructor pops the sigjmp_buf
  55. /// from the stack.
  56. ///
  57. /// The poco_throw_on_signal macro creates an instance of SignalHandler
  58. /// on the stack, which results in a new sigjmp_buf being created.
  59. /// The sigjmp_buf is then set-up with sigsetjmp().
  60. ///
  61. /// The handleSignal() method, which is invoked when a signal arrives,
  62. /// checks if a sigjmp_buf is available for the current thread.
  63. /// If so, siglongjmp() is used to jump out of the signal handler.
  64. ///
  65. /// Typical usage is as follows:
  66. ///
  67. /// try
  68. /// {
  69. /// poco_throw_on_signal;
  70. /// ...
  71. /// }
  72. /// catch (Poco::SignalException&)
  73. /// {
  74. /// ...
  75. /// }
  76. ///
  77. /// The best way to deal with a SignalException is to log as much context
  78. /// information as possible, to aid in debugging, and then to exit.
  79. ///
  80. /// The SignalHandler can be disabled globally by compiling POCO and client
  81. /// code with the POCO_NO_SIGNAL_HANDLER macro defined.
  82. {
  83. public:
  84. SignalHandler();
  85. /// Creates the SignalHandler.
  86. ~SignalHandler();
  87. /// Destroys the SignalHandler.
  88. sigjmp_buf& jumpBuffer();
  89. /// Returns the top-most sigjmp_buf for the current thread.
  90. static void throwSignalException(int sig);
  91. /// Throws a SignalException with a textual description
  92. /// of the given signal as argument.
  93. static void install();
  94. /// Installs signal handlers for SIGILL, SIGBUS, SIGSEGV
  95. /// and SIGSYS.
  96. protected:
  97. static void handleSignal(int sig);
  98. /// The actual signal handler.
  99. struct JumpBuffer
  100. /// sigjmp_buf cannot be used to instantiate a std::vector,
  101. /// so we provide a wrapper struct.
  102. {
  103. sigjmp_buf buf;
  104. };
  105. typedef std::vector<JumpBuffer> JumpBufferVec;
  106. static JumpBufferVec& jumpBufferVec();
  107. /// Returns the JumpBufferVec for the current thread.
  108. private:
  109. static JumpBufferVec _jumpBufferVec;
  110. friend class ThreadImpl;
  111. };
  112. #ifndef POCO_NO_SIGNAL_HANDLER
  113. #define poco_throw_on_signal \
  114. Poco::SignalHandler _poco_signalHandler; \
  115. int _poco_signal = sigsetjmp(_poco_signalHandler.jumpBuffer(), 1); \
  116. if (_poco_signal) _poco_signalHandler.throwSignalException(_poco_signal);
  117. #else
  118. #define poco_throw_on_signal
  119. #endif
  120. } // namespace Poco
  121. #endif // POCO_OS_FAMILY_UNIX
  122. #endif // Foundation_SignalHandler_INCLUDED