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 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 //---------------------------------------------------------------------- 43 UnixSignals::UnixSignals () 44 { 45 Reset (); 46 } 47 48 //---------------------------------------------------------------------- 49 // Destructor 50 //---------------------------------------------------------------------- 51 UnixSignals::~UnixSignals () 52 { 53 } 54 55 void 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 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 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 * 122 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 133 UnixSignals::SignalIsValid (int32_t signo) const 134 { 135 return m_signals.find (signo) != m_signals.end(); 136 } 137 138 139 int32_t 140 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 158 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 167 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 * 184 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 206 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 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 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 236 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 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 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 266 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 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 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