1 //===-- UnixSignals.cpp -----------------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/Target/UnixSignals.h"
11
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Interpreter/Args.h"
17
18 using namespace lldb_private;
19
Signal(const char * name,const char * short_name,bool default_suppress,bool default_stop,bool default_notify,const char * description)20 UnixSignals::Signal::Signal
21 (
22 const char *name,
23 const char *short_name,
24 bool default_suppress,
25 bool default_stop,
26 bool default_notify,
27 const char *description
28 ) :
29 m_name (name),
30 m_short_name (short_name),
31 m_description (),
32 m_suppress (default_suppress),
33 m_stop (default_stop),
34 m_notify (default_notify)
35 {
36 if (description)
37 m_description.assign (description);
38 }
39
40 //----------------------------------------------------------------------
41 // UnixSignals constructor
42 //----------------------------------------------------------------------
UnixSignals()43 UnixSignals::UnixSignals ()
44 {
45 Reset ();
46 }
47
48 //----------------------------------------------------------------------
49 // Destructor
50 //----------------------------------------------------------------------
~UnixSignals()51 UnixSignals::~UnixSignals ()
52 {
53 }
54
55 void
Reset()56 UnixSignals::Reset ()
57 {
58 // This builds one standard set of Unix Signals. If yours aren't quite in this
59 // order, you can either subclass this class, and use Add & Remove to change them
60 // or you can subclass and build them afresh in your constructor;
61 m_signals.clear();
62 // SIGNO NAME SHORT NAME SUPPRESS STOP NOTIFY DESCRIPTION
63 // ====== ============ ========== ======== ====== ====== ===================================================
64 AddSignal (1, "SIGHUP", "HUP", false, true , true , "hangup");
65 AddSignal (2, "SIGINT", "INT", true , true , true , "interrupt");
66 AddSignal (3, "SIGQUIT", "QUIT", false, true , true , "quit");
67 AddSignal (4, "SIGILL", "ILL", false, true , true , "illegal instruction");
68 AddSignal (5, "SIGTRAP", "TRAP", true , true , true , "trace trap (not reset when caught)");
69 AddSignal (6, "SIGABRT", "ABRT", false, true , true , "abort()");
70 AddSignal (7, "SIGEMT", "EMT", false, true , true , "pollable event");
71 AddSignal (8, "SIGFPE", "FPE", false, true , true , "floating point exception");
72 AddSignal (9, "SIGKILL", "KILL", false, true , true , "kill");
73 AddSignal (10, "SIGBUS", "BUS", false, true , true , "bus error");
74 AddSignal (11, "SIGSEGV", "SEGV", false, true , true , "segmentation violation");
75 AddSignal (12, "SIGSYS", "SYS", false, true , true , "bad argument to system call");
76 AddSignal (13, "SIGPIPE", "PIPE", false, true , true , "write on a pipe with no one to read it");
77 AddSignal (14, "SIGALRM", "ALRM", false, false, true , "alarm clock");
78 AddSignal (15, "SIGTERM", "TERM", false, true , true , "software termination signal from kill");
79 AddSignal (16, "SIGURG", "URG", false, false, false, "urgent condition on IO channel");
80 AddSignal (17, "SIGSTOP", "STOP", true , true , true , "sendable stop signal not from tty");
81 AddSignal (18, "SIGTSTP", "TSTP", false, true , true , "stop signal from tty");
82 AddSignal (19, "SIGCONT", "CONT", false, true , true , "continue a stopped process");
83 AddSignal (20, "SIGCHLD", "CHLD", false, false, true , "to parent on child stop or exit");
84 AddSignal (21, "SIGTTIN", "TTIN", false, true , true , "to readers process group upon background tty read");
85 AddSignal (22, "SIGTTOU", "TTOU", false, true , true , "to readers process group upon background tty write");
86 AddSignal (23, "SIGIO", "IO", false, false, false, "input/output possible signal");
87 AddSignal (24, "SIGXCPU", "XCPU", false, true , true , "exceeded CPU time limit");
88 AddSignal (25, "SIGXFSZ", "XFSZ", false, true , true , "exceeded file size limit");
89 AddSignal (26, "SIGVTALRM", "VTALRM", false, false, false, "virtual time alarm");
90 AddSignal (27, "SIGPROF", "PROF", false, false, false, "profiling time alarm");
91 AddSignal (28, "SIGWINCH", "WINCH", false, false, false, "window size changes");
92 AddSignal (29, "SIGINFO", "INFO", false, true , true , "information request");
93 AddSignal (30, "SIGUSR1", "USR1", false, true , true , "user defined signal 1");
94 AddSignal (31, "SIGUSR2", "USR2", false, true , true , "user defined signal 2");
95 }
96
97 void
AddSignal(int signo,const char * name,const char * short_name,bool default_suppress,bool default_stop,bool default_notify,const char * description)98 UnixSignals::AddSignal
99 (
100 int signo,
101 const char *name,
102 const char *short_name,
103 bool default_suppress,
104 bool default_stop,
105 bool default_notify,
106 const char *description
107 )
108 {
109 Signal new_signal (name, short_name, default_suppress, default_stop, default_notify, description);
110 m_signals.insert (std::make_pair(signo, new_signal));
111 }
112
113 void
RemoveSignal(int signo)114 UnixSignals::RemoveSignal (int signo)
115 {
116 collection::iterator pos = m_signals.find (signo);
117 if (pos != m_signals.end())
118 m_signals.erase (pos);
119 }
120
121 const char *
GetSignalAsCString(int signo) const122 UnixSignals::GetSignalAsCString (int signo) const
123 {
124 collection::const_iterator pos = m_signals.find (signo);
125 if (pos == m_signals.end())
126 return NULL;
127 else
128 return pos->second.m_name.GetCString ();
129 }
130
131
132 bool
SignalIsValid(int32_t signo) const133 UnixSignals::SignalIsValid (int32_t signo) const
134 {
135 return m_signals.find (signo) != m_signals.end();
136 }
137
138
139 int32_t
GetSignalNumberFromName(const char * name) const140 UnixSignals::GetSignalNumberFromName (const char *name) const
141 {
142 ConstString const_name (name);
143
144 collection::const_iterator pos, end = m_signals.end ();
145 for (pos = m_signals.begin (); pos != end; pos++)
146 {
147 if ((const_name == pos->second.m_name) || (const_name == pos->second.m_short_name))
148 return pos->first;
149 }
150
151 const int32_t signo = Args::StringToSInt32(name, LLDB_INVALID_SIGNAL_NUMBER, 0);
152 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
153 return signo;
154 return LLDB_INVALID_SIGNAL_NUMBER;
155 }
156
157 int32_t
GetFirstSignalNumber() const158 UnixSignals::GetFirstSignalNumber () const
159 {
160 if (m_signals.empty())
161 return LLDB_INVALID_SIGNAL_NUMBER;
162
163 return (*m_signals.begin ()).first;
164 }
165
166 int32_t
GetNextSignalNumber(int32_t current_signal) const167 UnixSignals::GetNextSignalNumber (int32_t current_signal) const
168 {
169 collection::const_iterator pos = m_signals.find (current_signal);
170 collection::const_iterator end = m_signals.end();
171 if (pos == end)
172 return LLDB_INVALID_SIGNAL_NUMBER;
173 else
174 {
175 pos++;
176 if (pos == end)
177 return LLDB_INVALID_SIGNAL_NUMBER;
178 else
179 return pos->first;
180 }
181 }
182
183 const char *
GetSignalInfo(int32_t signo,bool & should_suppress,bool & should_stop,bool & should_notify) const184 UnixSignals::GetSignalInfo
185 (
186 int32_t signo,
187 bool &should_suppress,
188 bool &should_stop,
189 bool &should_notify
190 ) const
191 {
192 collection::const_iterator pos = m_signals.find (signo);
193 if (pos == m_signals.end())
194 return NULL;
195 else
196 {
197 const Signal &signal = pos->second;
198 should_suppress = signal.m_suppress;
199 should_stop = signal.m_stop;
200 should_notify = signal.m_notify;
201 return signal.m_name.AsCString("");
202 }
203 }
204
205 bool
GetShouldSuppress(int signo) const206 UnixSignals::GetShouldSuppress (int signo) const
207 {
208 collection::const_iterator pos = m_signals.find (signo);
209 if (pos != m_signals.end())
210 return pos->second.m_suppress;
211 return false;
212 }
213
214 bool
SetShouldSuppress(int signo,bool value)215 UnixSignals::SetShouldSuppress (int signo, bool value)
216 {
217 collection::iterator pos = m_signals.find (signo);
218 if (pos != m_signals.end())
219 {
220 pos->second.m_suppress = value;
221 return true;
222 }
223 return false;
224 }
225
226 bool
SetShouldSuppress(const char * signal_name,bool value)227 UnixSignals::SetShouldSuppress (const char *signal_name, bool value)
228 {
229 const int32_t signo = GetSignalNumberFromName (signal_name);
230 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
231 return SetShouldSuppress (signo, value);
232 return false;
233 }
234
235 bool
GetShouldStop(int signo) const236 UnixSignals::GetShouldStop (int signo) const
237 {
238 collection::const_iterator pos = m_signals.find (signo);
239 if (pos != m_signals.end())
240 return pos->second.m_stop;
241 return false;
242 }
243
244 bool
SetShouldStop(int signo,bool value)245 UnixSignals::SetShouldStop (int signo, bool value)
246 {
247 collection::iterator pos = m_signals.find (signo);
248 if (pos != m_signals.end())
249 {
250 pos->second.m_stop = value;
251 return true;
252 }
253 return false;
254 }
255
256 bool
SetShouldStop(const char * signal_name,bool value)257 UnixSignals::SetShouldStop (const char *signal_name, bool value)
258 {
259 const int32_t signo = GetSignalNumberFromName (signal_name);
260 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
261 return SetShouldStop (signo, value);
262 return false;
263 }
264
265 bool
GetShouldNotify(int signo) const266 UnixSignals::GetShouldNotify (int signo) const
267 {
268 collection::const_iterator pos = m_signals.find (signo);
269 if (pos != m_signals.end())
270 return pos->second.m_notify;
271 return false;
272 }
273
274 bool
SetShouldNotify(int signo,bool value)275 UnixSignals::SetShouldNotify (int signo, bool value)
276 {
277 collection::iterator pos = m_signals.find (signo);
278 if (pos != m_signals.end())
279 {
280 pos->second.m_notify = value;
281 return true;
282 }
283 return false;
284 }
285
286 bool
SetShouldNotify(const char * signal_name,bool value)287 UnixSignals::SetShouldNotify (const char *signal_name, bool value)
288 {
289 const int32_t signo = GetSignalNumberFromName (signal_name);
290 if (signo != LLDB_INVALID_SIGNAL_NUMBER)
291 return SetShouldNotify (signo, value);
292 return false;
293 }
294