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