UnixSignals.cpp revision 258054
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 18using namespace lldb_private; 19 20UnixSignals::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//---------------------------------------------------------------------- 43UnixSignals::UnixSignals () 44{ 45 Reset (); 46} 47 48//---------------------------------------------------------------------- 49// Destructor 50//---------------------------------------------------------------------- 51UnixSignals::~UnixSignals () 52{ 53} 54 55void 56UnixSignals::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, false, "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, false, "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 97void 98UnixSignals::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 113void 114UnixSignals::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 121const char * 122UnixSignals::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 132bool 133UnixSignals::SignalIsValid (int32_t signo) const 134{ 135 return m_signals.find (signo) != m_signals.end(); 136} 137 138 139int32_t 140UnixSignals::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 157int32_t 158UnixSignals::GetFirstSignalNumber () const 159{ 160 if (m_signals.empty()) 161 return LLDB_INVALID_SIGNAL_NUMBER; 162 163 return (*m_signals.begin ()).first; 164} 165 166int32_t 167UnixSignals::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 183const char * 184UnixSignals::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 205bool 206UnixSignals::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 214bool 215UnixSignals::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 226bool 227UnixSignals::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 235bool 236UnixSignals::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 244bool 245UnixSignals::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 256bool 257UnixSignals::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 265bool 266UnixSignals::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 274bool 275UnixSignals::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 286bool 287UnixSignals::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