1 | // |
2 | // SignalHandler.cpp |
3 | // |
4 | // Library: Foundation |
5 | // Package: Threading |
6 | // Module: SignalHandler |
7 | // |
8 | // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. |
9 | // and Contributors. |
10 | // |
11 | // SPDX-License-Identifier: BSL-1.0 |
12 | // |
13 | |
14 | |
15 | #include "Poco/SignalHandler.h" |
16 | |
17 | |
18 | #if defined(POCO_OS_FAMILY_UNIX) && !defined(POCO_VXWORKS) |
19 | |
20 | |
21 | #include "Poco/Thread.h" |
22 | #include "Poco/NumberFormatter.h" |
23 | #include "Poco/Exception.h" |
24 | #include <cstdlib> |
25 | #include <signal.h> |
26 | |
27 | |
28 | namespace Poco { |
29 | |
30 | |
31 | SignalHandler::JumpBufferVec SignalHandler::_jumpBufferVec; |
32 | |
33 | |
34 | SignalHandler::SignalHandler() |
35 | { |
36 | JumpBufferVec& jbv = jumpBufferVec(); |
37 | JumpBuffer buf; |
38 | jbv.push_back(buf); |
39 | } |
40 | |
41 | |
42 | SignalHandler::~SignalHandler() |
43 | { |
44 | jumpBufferVec().pop_back(); |
45 | } |
46 | |
47 | |
48 | sigjmp_buf& SignalHandler::jumpBuffer() |
49 | { |
50 | return jumpBufferVec().back().buf; |
51 | } |
52 | |
53 | |
54 | void SignalHandler::throwSignalException(int sig) |
55 | { |
56 | switch (sig) |
57 | { |
58 | case SIGILL: |
59 | throw SignalException("Illegal instruction" ); |
60 | case SIGBUS: |
61 | throw SignalException("Bus error" ); |
62 | case SIGSEGV: |
63 | throw SignalException("Segmentation violation" ); |
64 | case SIGSYS: |
65 | throw SignalException("Invalid system call" ); |
66 | default: |
67 | throw SignalException(NumberFormatter::formatHex(sig)); |
68 | } |
69 | } |
70 | |
71 | |
72 | void SignalHandler::install() |
73 | { |
74 | #ifndef POCO_NO_SIGNAL_HANDLER |
75 | struct sigaction sa; |
76 | sa.sa_handler = handleSignal; |
77 | sa.sa_flags = 0; |
78 | sigemptyset(&sa.sa_mask); |
79 | sigaction(SIGILL, &sa, 0); |
80 | sigaction(SIGBUS, &sa, 0); |
81 | sigaction(SIGSEGV, &sa, 0); |
82 | sigaction(SIGSYS, &sa, 0); |
83 | #endif |
84 | } |
85 | |
86 | |
87 | void SignalHandler::handleSignal(int sig) |
88 | { |
89 | JumpBufferVec& jb = jumpBufferVec(); |
90 | if (!jb.empty()) |
91 | siglongjmp(jb.back().buf, sig); |
92 | |
93 | // Abort if no jump buffer registered |
94 | std::abort(); |
95 | } |
96 | |
97 | |
98 | SignalHandler::JumpBufferVec& SignalHandler::jumpBufferVec() |
99 | { |
100 | ThreadImpl* pThread = ThreadImpl::currentImpl(); |
101 | if (pThread) |
102 | return pThread->_jumpBufferVec; |
103 | else |
104 | return _jumpBufferVec; |
105 | } |
106 | |
107 | |
108 | } // namespace Poco |
109 | |
110 | |
111 | #endif // POCO_OS_FAMILY_UNIX |
112 | |