timemory 3.3.0
Modular C++ Toolkit for Performance Analysis and Logging. Profiling API and Tools for C, C++, CUDA, Fortran, and Python. The C++ template API is essentially a framework to creating tools: it is designed to provide a unifying interface for recording various performance measurements alongside data logging and interfaces to other tools.
signals.hpp
Go to the documentation of this file.
1// MIT License
2//
3// Copyright (c) 2020, The Regents of the University of California,
4// through Lawrence Berkeley National Laboratory (subject to receipt of any
5// required approvals from the U.S. Dept. of Energy). All rights reserved.
6//
7// Permission is hereby granted, free of charge, to any person obtaining a copy
8// of this software and associated documentation files (the "Software"), to deal
9// in the Software without restriction, including without limitation the rights
10// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11// copies of the Software, and to permit persons to whom the Software is
12// furnished to do so, subject to the following conditions:
13//
14// The above copyright notice and this permission notice shall be included in
15// all copies or substantial portions of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23// SOFTWARE.
24//
25
26/** \file utility/bits/signals.hpp
27 * \headerfile utility/bits/signals.hpp "timemory/utility/bits/signals.hpp"
28 * Provides inline implementation of signal_detection functions
29 *
30 */
31
32#pragma once
33
35
36#include <cstdlib>
37#include <iomanip>
38#include <sstream>
39#include <string>
40
41namespace tim
42{
43//======================================================================================//
44
46{
47#if defined(DEBUG)
50#else
52#endif
53}
54
55//======================================================================================//
56
57inline void
58insert_and_remove(const sys_signal& _type, // signal type
59 signal_settings::signal_set_t* _ins, // set to insert into
60 signal_settings::signal_set_t* _rem) // set to remove from
61
62{
63 if(!_ins || !_rem)
64 return;
65 _ins->insert(_type);
66 auto itr = _rem->find(_type);
67 if(itr != _rem->end())
68 _rem->erase(itr);
69}
70
71//======================================================================================//
72
73inline void
75{
76 insert_and_remove(_type, &f_signals().signals_enabled, &f_signals().signals_disabled);
77}
78
79//======================================================================================//
80
81inline void
83{
84 insert_and_remove(_type, &f_signals().signals_disabled, &f_signals().signals_enabled);
85}
86
87//======================================================================================//
88
89inline void
91{
92 using match_t = std::pair<std::string, sys_signal>;
93
94 auto _list = {
95 match_t("HANGUP", sys_signal::Hangup),
96 match_t("INTERRUPT", sys_signal::Interrupt),
97 match_t("QUIT", sys_signal::Quit),
98 match_t("ILLEGAL", sys_signal::Illegal),
99 match_t("TRAP", sys_signal::Trap),
100 match_t("ABORT", sys_signal::Abort),
101 match_t("EMULATE", sys_signal::Emulate),
102 match_t("FPE", sys_signal::FPE),
103 match_t("KILL", sys_signal::Kill),
104 match_t("BUS", sys_signal::Bus),
105 match_t("SEGFAULT", sys_signal::SegFault),
106 match_t("SYSTEM", sys_signal::System),
107 match_t("PIPE", sys_signal::Pipe),
108 match_t("ALARM", sys_signal::Alarm),
109 match_t("TERMINATE", sys_signal::Terminate),
110 match_t("URGENT", sys_signal::Urgent),
111 match_t("STOP", sys_signal::Stop),
112 match_t("CPUTIME", sys_signal::CPUtime),
113 match_t("FILESIZE", sys_signal::FileSize),
114 match_t("VIRTUALALARM", sys_signal::VirtualAlarm),
115 match_t("PROFILEALARM", sys_signal::ProfileAlarm),
116 match_t("USER1", sys_signal::User1),
117 match_t("USER2", sys_signal::User2),
118 };
119
120 for(const auto& itr : _list)
121 {
122 auto _enable = get_env("SIGNAL_ENABLE_" + itr.first, false);
123 auto _disable = get_env("SIGNAL_DISABLE_" + itr.first, false);
124
125 if(_enable)
126 signal_settings::enable(itr.second);
127 if(_disable)
128 signal_settings::disable(itr.second);
129 }
130
131 if(enable_all())
132 {
133 for(const auto& itr : _list)
134 signal_settings::enable(itr.second);
135 }
136
137 if(disable_all())
138 {
139 for(const auto& itr : _list)
140 signal_settings::disable(itr.second);
141 }
142}
143
144//======================================================================================//
145
146inline std::string
148{
149 using descript_tuple_t = std::tuple<std::string, int, std::string>;
150
151 std::stringstream ss;
152 auto _descript = [&](const descript_tuple_t& _data) {
153 ss << " Signal: " << std::setw(10) << std::get<0>(_data)
154 << " (error code: " << std::setw(3) << std::get<1>(_data) << ") "
155 << std::setw(40) << std::get<2>(_data);
156 };
157
158 // some of these signals are not handled but added in case they are
159 // enabled in the future
160 static std::vector<descript_tuple_t> descript_data = {
161 descript_tuple_t("SIGHUP", SIGHUP, "terminal line hangup"),
162 descript_tuple_t("SIGINT", SIGINT, "interrupt program"),
163 descript_tuple_t("SIGQUIT", SIGQUIT, "quit program"),
164 descript_tuple_t("SIGILL", SIGILL, "illegal instruction"),
165 descript_tuple_t("SIGTRAP", SIGTRAP, "trace trap"),
166 descript_tuple_t("SIGABRT", SIGABRT, "abort program (formerly SIGIOT)"),
167 descript_tuple_t("SIGEMT", SIGEMT, "emulate instruction executed"),
168 descript_tuple_t("SIGFPE", SIGFPE, "floating-point exception"),
169 descript_tuple_t("SIGKILL", SIGKILL, "kill program"),
170 descript_tuple_t("SIGBUS", SIGBUS, "bus error"),
171 descript_tuple_t("SIGSEGV", SIGSEGV, "segmentation violation"),
172 descript_tuple_t("SIGSYS", SIGSYS, "non-existent system call invoked"),
173 descript_tuple_t("SIGPIPE", SIGPIPE, "write on a pipe with no reader"),
174 descript_tuple_t("SIGALRM", SIGALRM, "real-time timer expired"),
175 descript_tuple_t("SIGTERM", SIGTERM, "software termination signal"),
176 descript_tuple_t("SIGURG", SIGURG, "urgent condition present on socket"),
177 descript_tuple_t("SIGSTOP", SIGSTOP, "stop (cannot be caught or ignored)"),
178 descript_tuple_t("SIGTSTP", SIGTSTP, "stop signal generated from keyboard"),
179 descript_tuple_t("SIGCONT", SIGCONT, "continue after stop"),
180 descript_tuple_t("SIGCHLD", SIGCHLD, "child status has changed"),
181 descript_tuple_t("SIGTTIN", SIGTTIN,
182 "background read attempted from control terminal"),
183 descript_tuple_t("SIGTTOU", SIGTTOU,
184 "background write attempted to control terminal"),
185 descript_tuple_t("SIGIO ", SIGIO, "I/O is possible on a descriptor"),
186 descript_tuple_t("SIGXCPU", SIGXCPU, "cpu time limit exceeded"),
187 descript_tuple_t("SIGXFSZ", SIGXFSZ, "file size limit exceeded"),
188 descript_tuple_t("SIGVTALRM", SIGVTALRM, "virtual time alarm"),
189 descript_tuple_t("SIGPROF", SIGPROF, "profiling timer alarm"),
190 descript_tuple_t("SIGWINCH", SIGWINCH, "Window size change"),
191 descript_tuple_t("SIGINFO", SIGINFO, "status request from keyboard"),
192 descript_tuple_t("SIGUSR1", SIGUSR1, "User defined signal 1"),
193 descript_tuple_t("SIGUSR2", SIGUSR2, "User defined signal 2")
194 };
195
196 int key = (int) _type;
197 for(const auto& itr : descript_data)
198 {
199 if(std::get<1>(itr) == key)
200 {
201 _descript(itr);
202 break;
203 }
204 }
205
206 return ss.str();
207}
208
209//======================================================================================//
210
211inline std::string
212signal_settings::str(bool report_disabled)
213{
214 std::stringstream ss;
215 auto spacer = []() { return " "; };
216
217#if defined(SIGNAL_AVAILABLE)
218
219 ss << std::endl
220 << spacer() << "Signal detection activated. Signal exception settings:\n"
221 << std::endl;
222
223 if(report_disabled)
224 ss << spacer() << "Enabled:" << std::endl;
225 for(const auto& itr : f_signals().signals_enabled)
226 ss << spacer() << spacer() << signal_settings::str(itr) << '\n';
227
228 if(report_disabled)
229 {
230 ss << "\n" << spacer() << "Disabled:" << std::endl;
231 for(const auto& itr : f_signals().signals_disabled)
232 ss << spacer() << spacer() << signal_settings::str(itr) << '\n';
233 }
234
235#else
236
237 ss << std::endl << spacer() << "Signal detection not available" << std::endl;
238
239 (void) report_disabled;
240#endif
241
242 return ss.str();
243}
244
245//======================================================================================//
246
247inline bool
249{
250 return f_signals().signals_active;
251}
252
253//======================================================================================//
254
255inline bool&
257{
258 return f_signals().enable_all;
259}
260
261//======================================================================================//
262
263inline bool&
265{
266 return f_signals().disable_all;
267}
268
269//======================================================================================//
270
271inline void
273{
275}
276
277//======================================================================================//
278
279inline void
281{
282 f_signals().signals_exit_func = std::move(_f);
283}
284
285//======================================================================================//
286
287inline void
289{
290 f_signals().signals_exit_func(errcode);
291}
292
293//======================================================================================//
294
297{
298 return f_signals().signals_enabled;
299}
300
301//======================================================================================//
302
305{
307}
308
309//======================================================================================//
310
313{
314 return f_signals().signals_default;
315}
316
317//======================================================================================//
318
319} // namespace tim
320
321//======================================================================================//
static std::string str(const sys_signal &)
Definition: signals.hpp:147
static void enable(const sys_signal &)
Definition: signals.hpp:74
static void check_environment()
Definition: signals.hpp:90
static void exit_action(int errcode)
Definition: signals.hpp:288
static bool & enable_all()
Definition: signals.hpp:256
static void disable(const sys_signal &)
Definition: signals.hpp:82
static signal_set_t get_enabled()
Definition: signals.hpp:296
std::set< sys_signal > signal_set_t
std::function< void(int)> signal_function_t
static void set_active(bool val)
Definition: signals.hpp:272
static signal_set_t get_disabled()
Definition: signals.hpp:304
static void set_exit_action(signal_function_t _f)
Definition: signals.hpp:280
static bool is_active()
Definition: signals.hpp:248
static bool & disable_all()
Definition: signals.hpp:264
static signal_set_t get_default()
Definition: signals.hpp:312
static signals_data & f_signals()
Definition: kokkosp.cpp:39
sys_signal
Definition: declaration.hpp:69
void insert_and_remove(const sys_signal &_type, signal_settings::signal_set_t *_ins, signal_settings::signal_set_t *_rem)
Definition: signals.hpp:58
Tp get_env(const std::string &env_id, Tp _default, bool _store)
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
The declaration for the types for utility without definitions.