LLDB  mainline
UnixSignals.cpp
Go to the documentation of this file.
1 //===-- UnixSignals.cpp ---------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
14 #include "lldb/Host/HostInfo.h"
15 #include "lldb/Utility/ArchSpec.h"
16 
17 using namespace lldb_private;
18 
19 UnixSignals::Signal::Signal(const char *name, bool default_suppress,
20  bool default_stop, bool default_notify,
21  const char *description, const char *alias)
22  : m_name(name), m_alias(alias), m_description(),
23  m_suppress(default_suppress), m_stop(default_stop),
24  m_notify(default_notify) {
25  if (description)
26  m_description.assign(description);
27 }
28 
29 lldb::UnixSignalsSP UnixSignals::Create(const ArchSpec &arch) {
30  const auto &triple = arch.GetTriple();
31  switch (triple.getOS()) {
32  case llvm::Triple::Linux: {
33  switch (triple.getArch()) {
34  case llvm::Triple::mips:
35  case llvm::Triple::mipsel:
36  case llvm::Triple::mips64:
37  case llvm::Triple::mips64el:
38  return std::make_shared<MipsLinuxSignals>();
39  default:
40  return std::make_shared<LinuxSignals>();
41  }
42  }
43  case llvm::Triple::FreeBSD:
44  case llvm::Triple::OpenBSD:
45  return std::make_shared<FreeBSDSignals>();
46  case llvm::Triple::NetBSD:
47  return std::make_shared<NetBSDSignals>();
48  default:
49  return std::make_shared<UnixSignals>();
50  }
51 }
52 
53 lldb::UnixSignalsSP UnixSignals::CreateForHost() {
54  static lldb::UnixSignalsSP s_unix_signals_sp =
55  Create(HostInfo::GetArchitecture());
56  return s_unix_signals_sp;
57 }
58 
59 // UnixSignals constructor
61 
63 
64 UnixSignals::~UnixSignals() = default;
65 
67  // This builds one standard set of Unix Signals. If yours aren't quite in
68  // this order, you can either subclass this class, and use Add & Remove to
69  // change them or you can subclass and build them afresh in your constructor.
70  //
71  // Note: the signals below are the Darwin signals. Do not change these!
72 
73  m_signals.clear();
74 
75  // clang-format off
76  // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION
77  // ====== ============== ======== ====== ====== ===================================================
78  AddSignal(1, "SIGHUP", false, true, true, "hangup");
79  AddSignal(2, "SIGINT", true, true, true, "interrupt");
80  AddSignal(3, "SIGQUIT", false, true, true, "quit");
81  AddSignal(4, "SIGILL", false, true, true, "illegal instruction");
82  AddSignal(5, "SIGTRAP", true, true, true, "trace trap (not reset when caught)");
83  AddSignal(6, "SIGABRT", false, true, true, "abort()");
84  AddSignal(7, "SIGEMT", false, true, true, "pollable event");
85  AddSignal(8, "SIGFPE", false, true, true, "floating point exception");
86  AddSignal(9, "SIGKILL", false, true, true, "kill");
87  AddSignal(10, "SIGBUS", false, true, true, "bus error");
88  AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation");
89  AddSignal(12, "SIGSYS", false, true, true, "bad argument to system call");
90  AddSignal(13, "SIGPIPE", false, false, false, "write on a pipe with no one to read it");
91  AddSignal(14, "SIGALRM", false, false, false, "alarm clock");
92  AddSignal(15, "SIGTERM", false, true, true, "software termination signal from kill");
93  AddSignal(16, "SIGURG", false, false, false, "urgent condition on IO channel");
94  AddSignal(17, "SIGSTOP", true, true, true, "sendable stop signal not from tty");
95  AddSignal(18, "SIGTSTP", false, true, true, "stop signal from tty");
96  AddSignal(19, "SIGCONT", false, false, true, "continue a stopped process");
97  AddSignal(20, "SIGCHLD", false, false, false, "to parent on child stop or exit");
98  AddSignal(21, "SIGTTIN", false, true, true, "to readers process group upon background tty read");
99  AddSignal(22, "SIGTTOU", false, true, true, "to readers process group upon background tty write");
100  AddSignal(23, "SIGIO", false, false, false, "input/output possible signal");
101  AddSignal(24, "SIGXCPU", false, true, true, "exceeded CPU time limit");
102  AddSignal(25, "SIGXFSZ", false, true, true, "exceeded file size limit");
103  AddSignal(26, "SIGVTALRM", false, false, false, "virtual time alarm");
104  AddSignal(27, "SIGPROF", false, false, false, "profiling time alarm");
105  AddSignal(28, "SIGWINCH", false, false, false, "window size changes");
106  AddSignal(29, "SIGINFO", false, true, true, "information request");
107  AddSignal(30, "SIGUSR1", false, true, true, "user defined signal 1");
108  AddSignal(31, "SIGUSR2", false, true, true, "user defined signal 2");
109  // clang-format on
110 }
111 
112 void UnixSignals::AddSignal(int signo, const char *name, bool default_suppress,
113  bool default_stop, bool default_notify,
114  const char *description, const char *alias) {
115  Signal new_signal(name, default_suppress, default_stop, default_notify,
116  description, alias);
117  m_signals.insert(std::make_pair(signo, new_signal));
118  ++m_version;
119 }
120 
121 void UnixSignals::RemoveSignal(int signo) {
122  collection::iterator pos = m_signals.find(signo);
123  if (pos != m_signals.end())
124  m_signals.erase(pos);
125  ++m_version;
126 }
127 
128 const char *UnixSignals::GetSignalAsCString(int signo) const {
129  collection::const_iterator pos = m_signals.find(signo);
130  if (pos == m_signals.end())
131  return nullptr;
132  else
133  return pos->second.m_name.GetCString();
134 }
135 
136 bool UnixSignals::SignalIsValid(int32_t signo) const {
137  return m_signals.find(signo) != m_signals.end();
138 }
139 
141  if (name)
142  return ConstString(name.GetStringRef().substr(3)); // Remove "SIG" from name
143  return name;
144 }
145 
146 int32_t UnixSignals::GetSignalNumberFromName(const char *name) const {
147  ConstString const_name(name);
148 
149  collection::const_iterator pos, end = m_signals.end();
150  for (pos = m_signals.begin(); pos != end; pos++) {
151  if ((const_name == pos->second.m_name) ||
152  (const_name == pos->second.m_alias) ||
153  (const_name == GetShortName(pos->second.m_name)) ||
154  (const_name == GetShortName(pos->second.m_alias)))
155  return pos->first;
156  }
157 
158  int32_t signo;
159  if (llvm::to_integer(name, signo))
160  return signo;
162 }
163 
165  if (m_signals.empty())
167 
168  return (*m_signals.begin()).first;
169 }
170 
171 int32_t UnixSignals::GetNextSignalNumber(int32_t current_signal) const {
172  collection::const_iterator pos = m_signals.find(current_signal);
173  collection::const_iterator end = m_signals.end();
174  if (pos == end)
176  else {
177  pos++;
178  if (pos == end)
180  else
181  return pos->first;
182  }
183 }
184 
185 const char *UnixSignals::GetSignalInfo(int32_t signo, bool &should_suppress,
186  bool &should_stop,
187  bool &should_notify) const {
188  collection::const_iterator pos = m_signals.find(signo);
189  if (pos == m_signals.end())
190  return nullptr;
191  else {
192  const Signal &signal = pos->second;
193  should_suppress = signal.m_suppress;
194  should_stop = signal.m_stop;
195  should_notify = signal.m_notify;
196  return signal.m_name.AsCString("");
197  }
198 }
199 
200 bool UnixSignals::GetShouldSuppress(int signo) const {
201  collection::const_iterator pos = m_signals.find(signo);
202  if (pos != m_signals.end())
203  return pos->second.m_suppress;
204  return false;
205 }
206 
207 bool UnixSignals::SetShouldSuppress(int signo, bool value) {
208  collection::iterator pos = m_signals.find(signo);
209  if (pos != m_signals.end()) {
210  pos->second.m_suppress = value;
211  ++m_version;
212  return true;
213  }
214  return false;
215 }
216 
217 bool UnixSignals::SetShouldSuppress(const char *signal_name, bool value) {
218  const int32_t signo = GetSignalNumberFromName(signal_name);
219  if (signo != LLDB_INVALID_SIGNAL_NUMBER)
220  return SetShouldSuppress(signo, value);
221  return false;
222 }
223 
224 bool UnixSignals::GetShouldStop(int signo) const {
225  collection::const_iterator pos = m_signals.find(signo);
226  if (pos != m_signals.end())
227  return pos->second.m_stop;
228  return false;
229 }
230 
231 bool UnixSignals::SetShouldStop(int signo, bool value) {
232  collection::iterator pos = m_signals.find(signo);
233  if (pos != m_signals.end()) {
234  pos->second.m_stop = value;
235  ++m_version;
236  return true;
237  }
238  return false;
239 }
240 
241 bool UnixSignals::SetShouldStop(const char *signal_name, bool value) {
242  const int32_t signo = GetSignalNumberFromName(signal_name);
243  if (signo != LLDB_INVALID_SIGNAL_NUMBER)
244  return SetShouldStop(signo, value);
245  return false;
246 }
247 
248 bool UnixSignals::GetShouldNotify(int signo) const {
249  collection::const_iterator pos = m_signals.find(signo);
250  if (pos != m_signals.end())
251  return pos->second.m_notify;
252  return false;
253 }
254 
255 bool UnixSignals::SetShouldNotify(int signo, bool value) {
256  collection::iterator pos = m_signals.find(signo);
257  if (pos != m_signals.end()) {
258  pos->second.m_notify = value;
259  ++m_version;
260  return true;
261  }
262  return false;
263 }
264 
265 bool UnixSignals::SetShouldNotify(const char *signal_name, bool value) {
266  const int32_t signo = GetSignalNumberFromName(signal_name);
267  if (signo != LLDB_INVALID_SIGNAL_NUMBER)
268  return SetShouldNotify(signo, value);
269  return false;
270 }
271 
272 int32_t UnixSignals::GetNumSignals() const { return m_signals.size(); }
273 
274 int32_t UnixSignals::GetSignalAtIndex(int32_t index) const {
275  if (index < 0 || m_signals.size() <= static_cast<size_t>(index))
277  auto it = m_signals.begin();
278  std::advance(it, index);
279  return it->first;
280 }
281 
282 uint64_t UnixSignals::GetVersion() const { return m_version; }
283 
284 std::vector<int32_t>
285 UnixSignals::GetFilteredSignals(llvm::Optional<bool> should_suppress,
286  llvm::Optional<bool> should_stop,
287  llvm::Optional<bool> should_notify) {
288  std::vector<int32_t> result;
289  for (int32_t signo = GetFirstSignalNumber();
291  signo = GetNextSignalNumber(signo)) {
292 
293  bool signal_suppress = false;
294  bool signal_stop = false;
295  bool signal_notify = false;
296  GetSignalInfo(signo, signal_suppress, signal_stop, signal_notify);
297 
298  // If any of filtering conditions are not met, we move on to the next
299  // signal.
300  if (should_suppress.hasValue() &&
301  signal_suppress != should_suppress.getValue())
302  continue;
303 
304  if (should_stop.hasValue() && signal_stop != should_stop.getValue())
305  continue;
306 
307  if (should_notify.hasValue() && signal_notify != should_notify.getValue())
308  continue;
309 
310  result.push_back(signo);
311  }
312 
313  return result;
314 }
lldb_private::UnixSignals::UnixSignals
UnixSignals()
Definition: UnixSignals.cpp:60
FreeBSDSignals.h
lldb_private::ArchSpec
Definition: ArchSpec.h:33
lldb_private::UnixSignals::GetShouldStop
bool GetShouldStop(int32_t signo) const
Definition: UnixSignals.cpp:224
LinuxSignals.h
lldb_private::UnixSignals::AddSignal
void AddSignal(int signo, const char *name, bool default_suppress, bool default_stop, bool default_notify, const char *description, const char *alias=nullptr)
Definition: UnixSignals.cpp:112
lldb_private::UnixSignals::Reset
virtual void Reset()
Definition: UnixSignals.cpp:66
lldb_private::UnixSignals::GetSignalNumberFromName
int32_t GetSignalNumberFromName(const char *name) const
Definition: UnixSignals.cpp:146
lldb_private::UnixSignals::RemoveSignal
void RemoveSignal(int signo)
Definition: UnixSignals.cpp:121
lldb_private::ConstString::AsCString
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:193
lldb_private::ArchSpec::GetTriple
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:444
lldb_private::UnixSignals::SetShouldSuppress
bool SetShouldSuppress(int32_t signo, bool value)
lldb_private::UnixSignals::GetShouldSuppress
bool GetShouldSuppress(int32_t signo) const
Definition: UnixSignals.cpp:200
lldb_private::UnixSignals::~UnixSignals
virtual ~UnixSignals()
lldb_private::UnixSignals::GetShouldNotify
bool GetShouldNotify(int32_t signo) const
Definition: UnixSignals.cpp:248
lldb_private::UnixSignals::Signal::Signal
Signal(const char *name, bool default_suppress, bool default_stop, bool default_notify, const char *description, const char *alias)
Definition: UnixSignals.cpp:19
lldb_private::UnixSignals::GetNumSignals
int32_t GetNumSignals() const
Definition: UnixSignals.cpp:272
lldb_private::UnixSignals::GetFirstSignalNumber
int32_t GetFirstSignalNumber() const
Definition: UnixSignals.cpp:164
LLDB_INVALID_SIGNAL_NUMBER
#define LLDB_INVALID_SIGNAL_NUMBER
Definition: lldb-defines.h:96
lldb_private::UnixSignals::m_version
uint64_t m_version
Definition: UnixSignals.h:120
lldb_private::UnixSignals::GetSignalAtIndex
int32_t GetSignalAtIndex(int32_t index) const
Definition: UnixSignals.cpp:274
lldb_private::ConstString::GetStringRef
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:202
UnixSignals.h
lldb_private::UnixSignals::Signal::m_name
ConstString m_name
Definition: UnixSignals.h:99
lldb_private::UnixSignals::SetShouldStop
bool SetShouldStop(int32_t signo, bool value)
lldb_private::UnixSignals::GetShortName
ConstString GetShortName(ConstString name) const
Definition: UnixSignals.cpp:140
lldb_private::UnixSignals::CreateForHost
static lldb::UnixSignalsSP CreateForHost()
Definition: UnixSignals.cpp:53
lldb_private::ConstString
Definition: ConstString.h:40
lldb_private::UnixSignals::GetVersion
uint64_t GetVersion() const
Definition: UnixSignals.cpp:282
lldb_private::UnixSignals::Signal::m_notify
bool m_notify
Definition: UnixSignals.h:102
lldb_private::UnixSignals
Definition: UnixSignals.h:22
lldb_private::UnixSignals::Signal
Definition: UnixSignals.h:98
HostInfo.h
lldb_private::UnixSignals::Signal::m_stop
bool m_stop
Definition: UnixSignals.h:102
lldb_private::UnixSignals::GetSignalInfo
const char * GetSignalInfo(int32_t signo, bool &should_suppress, bool &should_stop, bool &should_notify) const
Definition: UnixSignals.cpp:185
lldb_private::UnixSignals::GetNextSignalNumber
int32_t GetNextSignalNumber(int32_t current_signal) const
Definition: UnixSignals.cpp:171
lldb_private::UnixSignals::GetFilteredSignals
std::vector< int32_t > GetFilteredSignals(llvm::Optional< bool > should_suppress, llvm::Optional< bool > should_stop, llvm::Optional< bool > should_notify)
Definition: UnixSignals.cpp:285
lldb_private::UnixSignals::SignalIsValid
bool SignalIsValid(int32_t signo) const
Definition: UnixSignals.cpp:136
ArchSpec.h
lldb_private::UnixSignals::Signal::m_suppress
bool m_suppress
Definition: UnixSignals.h:102
MipsLinuxSignals.h
NetBSDSignals.h
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::UnixSignals::GetSignalAsCString
const char * GetSignalAsCString(int32_t signo) const
Definition: UnixSignals.cpp:128
lldb_private::UnixSignals::SetShouldNotify
bool SetShouldNotify(int32_t signo, bool value)
lldb_private::UnixSignals::Signal::m_description
std::string m_description
Definition: UnixSignals.h:101
lldb_private::UnixSignals::m_signals
collection m_signals
Definition: UnixSignals.h:114
lldb_private::UnixSignals::Create
static lldb::UnixSignalsSP Create(const ArchSpec &arch)
Definition: UnixSignals.cpp:29