1//
2// SignalHandler.h
3//
4// Library: Foundation
5// Package: Threading
6// Module: SignalHandler
7//
8// Definition of the SignalHandler class.
9//
10// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// SPDX-License-Identifier: BSL-1.0
14//
15
16
17#ifndef Foundation_SignalHandler_INCLUDED
18#define Foundation_SignalHandler_INCLUDED
19
20
21#include "Poco/Foundation.h"
22
23
24#if defined(POCO_OS_FAMILY_UNIX) && !defined(POCO_VXWORKS)
25
26
27#include <vector>
28#include <setjmp.h>
29
30
31namespace Poco {
32
33
34class Foundation_API SignalHandler
35 /// This helper class simplifies the handling of POSIX signals.
36 ///
37 /// The class provides a signal handler (installed with
38 /// installHandlers()) that translates certain POSIX
39 /// signals (SIGILL, SIGBUS, SIGSEGV, SIGSYS) into
40 /// C++ exceptions.
41 ///
42 /// Internally, a stack of sigjmp_buf structs is maintained for
43 /// each thread. The constructor pushes a new sigjmp_buf onto
44 /// the current thread's stack. The destructor pops the sigjmp_buf
45 /// from the stack.
46 ///
47 /// The poco_throw_on_signal macro creates an instance of SignalHandler
48 /// on the stack, which results in a new sigjmp_buf being created.
49 /// The sigjmp_buf is then set-up with sigsetjmp().
50 ///
51 /// The handleSignal() method, which is invoked when a signal arrives,
52 /// checks if a sigjmp_buf is available for the current thread.
53 /// If so, siglongjmp() is used to jump out of the signal handler.
54 ///
55 /// Typical usage is as follows:
56 ///
57 /// try
58 /// {
59 /// poco_throw_on_signal;
60 /// ...
61 /// }
62 /// catch (Poco::SignalException&)
63 /// {
64 /// ...
65 /// }
66 ///
67 /// The best way to deal with a SignalException is to log as much context
68 /// information as possible, to aid in debugging, and then to exit.
69 ///
70 /// The SignalHandler can be disabled globally by compiling POCO and client
71 /// code with the POCO_NO_SIGNAL_HANDLER macro defined.
72{
73public:
74 SignalHandler();
75 /// Creates the SignalHandler.
76
77 ~SignalHandler();
78 /// Destroys the SignalHandler.
79
80 sigjmp_buf& jumpBuffer();
81 /// Returns the top-most sigjmp_buf for the current thread.
82
83 static void throwSignalException(int sig);
84 /// Throws a SignalException with a textual description
85 /// of the given signal as argument.
86
87 static void install();
88 /// Installs signal handlers for SIGILL, SIGBUS, SIGSEGV
89 /// and SIGSYS.
90
91protected:
92 static void handleSignal(int sig);
93 /// The actual signal handler.
94
95 struct JumpBuffer
96 /// sigjmp_buf cannot be used to instantiate a std::vector,
97 /// so we provide a wrapper struct.
98 {
99 sigjmp_buf buf;
100 };
101 typedef std::vector<JumpBuffer> JumpBufferVec;
102
103 static JumpBufferVec& jumpBufferVec();
104 /// Returns the JumpBufferVec for the current thread.
105
106private:
107 static JumpBufferVec _jumpBufferVec;
108
109 friend class ThreadImpl;
110};
111
112
113#ifndef POCO_NO_SIGNAL_HANDLER
114#define poco_throw_on_signal \
115 Poco::SignalHandler _poco_signalHandler; \
116 int _poco_signal = sigsetjmp(_poco_signalHandler.jumpBuffer(), 1); \
117 if (_poco_signal) _poco_signalHandler.throwSignalException(_poco_signal);
118#else
119#define poco_throw_on_signal
120#endif
121
122
123} // namespace Poco
124
125
126#endif // POCO_OS_FAMILY_UNIX
127
128
129#endif // Foundation_SignalHandler_INCLUDED
130