libexcept 1.1.19
Stack trace along C++ exceptions
scoped_signal_mask.cpp
Go to the documentation of this file.
1// Copyright (c) 2019-2025 Made to Order Software Corp. All Rights Reserved
2//
3// https://snapwebsites.org/project/libexcept
4// contact@m2osw.com
5//
6// This program is free software; you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation; either version 2 of the License, or
9// (at your option) any later version.
10//
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License along
17// with this program; if not, write to the Free Software Foundation, Inc.,
18// 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
20// self
21//
23
24#include "libexcept/exception.h"
25
26
27// C++
28//
29#include <iostream>
30
31
32// C
33//
34#include <dlfcn.h>
35#include <signal.h>
36
37
46namespace libexcept
47{
48
49
50
51namespace
52{
53
54
55
56constexpr int const g_incompatible_signals[] = {
57 SIGHUP,
58 SIGINT,
59 SIGILL,
60 SIGABRT,
61 SIGFPE,
62 SIGKILL, // this one is not necessary rather than incompatible
63 SIGSEGV,
64 SIGTERM,
65 SIGCONT,
66 SIGSTOP,
67 SIGTSTP,
68 SIGPROF,
69 SIGIO,
70};
71
72
73bool g_defined = false;
74bool g_has_sanitizer = false;
75
76
77
78} // no name namespace
79
80
81
95{
96 sigset_t set;
97 sigemptyset(&set);
98
99 if(block_signals.empty())
100 {
101 // sigfillset() does not set the few signals that should never be
102 // blocked (would be ignored by the command below)
103 //
104 sigfillset(&set);
105 }
106 else
107 {
108 for(auto const & sig : block_signals)
109 {
110 if(sigaddset(&set, sig) != 0)
111 {
112 throw fixme("sigaddset() failed to set signal " + std::to_string(sig));
113 }
114 }
115 }
116
117 if(has_sanitizer())
118 {
119 for(auto const & sig : g_incompatible_signals)
120 {
121 if(sigdelset(&set, sig) != 0)
122 {
123 throw fixme("sigdelset() failed to delete signal " + std::to_string(sig));
124 }
125 }
126 }
127
128 if(sigprocmask(SIG_BLOCK, &set, &f_original_mask) != 0)
129 {
130 throw fixme("sigprocmask() failed to block signals.");
131 }
132
133 f_set = true;
134}
135
136
143{
144 if(f_set)
145 {
146 if(sigprocmask(SIG_SETMASK, &f_original_mask, nullptr) != 0)
147 {
148 std::cerr << "fatal error: sigprocmask() failed to block signals.\n";
149 std::terminate();
150 }
151 }
152}
153
154
169inline bool has_sanitizer()
170{
171 if(!g_defined)
172 {
173 g_defined = true;
174 g_has_sanitizer = dlsym(RTLD_DEFAULT, "__lsan_enable") != nullptr;
175 }
176
177 return g_has_sanitizer;
178}
179
180
181
182}
183// namespace libexcept
184// vim: ts=4 sw=4 et
~scoped_signal_mask()
Reset signal mask the way it was before the constructor was called.
scoped_signal_mask(sig_list_t block_signals=sig_list_t())
Set signal mask.
Declarations of the exception library.
bool has_sanitizer()
Check whether this instance is running with the sanitizer.
std::list< int > sig_list_t
Handle sigmask in a scoped manner (RAII).

This document is part of the Snap! Websites Project.

Copyright by Made to Order Software Corp.