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 17 using namespace lldb_private; 18 19 UnixSignals::Signal::Signal (const char *name, bool default_suppress, bool default_stop, bool default_notify) : 20 m_name (name), 21 m_conditions () 22 { 23 m_conditions[Signal::eCondSuppress] = default_suppress; 24 m_conditions[Signal::eCondStop] = default_stop; 25 m_conditions[Signal::eCondNotify] = default_notify; 26 } 27 28 //---------------------------------------------------------------------- 29 // UnixSignals constructor 30 //---------------------------------------------------------------------- 31 UnixSignals::UnixSignals () 32 { 33 Reset (); 34 } 35 36 //---------------------------------------------------------------------- 37 // Destructor 38 //---------------------------------------------------------------------- 39 UnixSignals::~UnixSignals () 40 { 41 } 42 43 void 44 UnixSignals::Reset () 45 { 46 // This builds one standard set of Unix Signals. If yours aren't quite in this 47 // order, you can either subclass this class, and use Add & Remove to change them 48 // or you can subclass and build them afresh in your constructor; 49 m_signals.clear(); 50 51 AddSignal(1, "SIGHUP", false, true, true ); // 1 hangup 52 AddSignal(2, "SIGINT", true, true, true ); // 2 interrupt 53 AddSignal(3, "SIGQUIT", false, true, true ); // 3 quit 54 AddSignal(4, "SIGILL", false, true, true ); // 4 illegal instruction (not reset when caught) 55 AddSignal(5, "SIGTRAP", true, true, true ); // 5 trace trap (not reset when caught) 56 AddSignal(6, "SIGABRT", false, true, true ); // 6 abort() 57 AddSignal(7, "SIGEMT", false, true, true ); // 7 pollable event ([XSR] generated, not supported) 58 AddSignal(8, "SIGFPE", false, true, true ); // 8 floating point exception 59 AddSignal(9, "SIGKILL", false, true, true ); // 9 kill (cannot be caught or ignored) 60 AddSignal(10, "SIGBUS", false, true, true ); // 10 bus error 61 AddSignal(11, "SIGSEGV", false, true, true ); // 11 segmentation violation 62 AddSignal(12, "SIGSYS", false, true, true ); // 12 bad argument to system call 63 AddSignal(13, "SIGPIPE", false, true, true ); // 13 write on a pipe with no one to read it 64 AddSignal(14, "SIGALRM", false, false, true ); // 14 alarm clock 65 AddSignal(15, "SIGTERM", false, true, true ); // 15 software termination signal from kill 66 AddSignal(16, "SIGURG", false, false, false); // 16 urgent condition on IO channel 67 AddSignal(17, "SIGSTOP", false, true, true ); // 17 sendable stop signal not from tty 68 AddSignal(18, "SIGTSTP", false, true, true ); // 18 stop signal from tty 69 AddSignal(19, "SIGCONT", false, true, true ); // 19 continue a stopped process 70 AddSignal(20, "SIGCHLD", false, false, true ); // 20 to parent on child stop or exit 71 AddSignal(21, "SIGTTIN", false, true, true ); // 21 to readers pgrp upon background tty read 72 AddSignal(22, "SIGTTOU", false, true, true ); // 22 like TTIN for output if (tp->t_local<OSTOP) 73 AddSignal(23, "SIGIO", false, false, false); // 23 input/output possible signal 74 AddSignal(24, "SIGXCPU", false, true, true ); // 24 exceeded CPU time limit 75 AddSignal(25, "SIGXFSZ", false, true, true ); // 25 exceeded file size limit 76 AddSignal(26, "SIGVTALRM", false, false, false); // 26 virtual time alarm 77 AddSignal(27, "SIGPROF", false, false, false); // 27 profiling time alarm 78 AddSignal(28, "SIGWINCH", false, false, false); // 28 window size changes 79 AddSignal(29, "SIGINFO", false, true, true ); // 29 information request 80 AddSignal(30, "SIGUSR1", false, true, true ); // 30 user defined signal 1 81 AddSignal(31, "SIGUSR2", false, true, true ); // 31 user defined signal 2 82 } 83 void 84 UnixSignals::AddSignal (int signo, const char *name, bool default_suppress, bool default_stop, bool default_notify) 85 { 86 collection::iterator iter = m_signals.find (signo); 87 struct Signal new_signal (name, default_suppress, default_stop, default_notify); 88 89 if (iter != m_signals.end()) 90 m_signals.erase (iter); 91 92 m_signals.insert (iter, collection::value_type (signo, new_signal)); 93 } 94 95 void 96 UnixSignals::RemoveSignal (int signo) 97 { 98 collection::iterator pos = m_signals.find (signo); 99 if (pos != m_signals.end()) 100 m_signals.erase (pos); 101 } 102 103 UnixSignals::Signal * 104 UnixSignals::GetSignalByName (const char *name, int32_t &signo) 105 { 106 ConstString const_name (name); 107 108 collection::iterator pos, end = m_signals.end (); 109 for (pos = m_signals.begin (); pos != end; pos++) 110 { 111 if (const_name == (*pos).second.m_name) 112 { 113 signo = (*pos).first; 114 return &((*pos).second); 115 } 116 } 117 return NULL; 118 } 119 120 121 const UnixSignals::Signal * 122 UnixSignals::GetSignalByName (const char *name, int32_t &signo) const 123 { 124 ConstString const_name (name); 125 126 collection::const_iterator pos, end = m_signals.end (); 127 for (pos = m_signals.begin (); pos != end; pos++) 128 { 129 if (const_name == (*pos).second.m_name) 130 { 131 signo = (*pos).first; 132 return &((*pos).second); 133 } 134 } 135 return NULL; 136 } 137 138 const char * 139 UnixSignals::GetSignalAsCString (int signo) const 140 { 141 collection::const_iterator pos = m_signals.find (signo); 142 if (pos == m_signals.end()) 143 return NULL; 144 else 145 return (*pos).second.m_name.GetCString (); 146 } 147 148 149 bool 150 UnixSignals::SignalIsValid (int32_t signo) const 151 { 152 return m_signals.find (signo) != m_signals.end(); 153 } 154 155 156 int32_t 157 UnixSignals::GetSignalNumberFromName (const char *name) const 158 { 159 int32_t signo; 160 const Signal *signal = GetSignalByName (name, signo); 161 if (signal == NULL) 162 return LLDB_INVALID_SIGNAL_NUMBER; 163 else 164 return signo; 165 } 166 167 int32_t 168 UnixSignals::GetFirstSignalNumber () const 169 { 170 if (m_signals.empty()) 171 return LLDB_INVALID_SIGNAL_NUMBER; 172 173 return (*m_signals.begin ()).first; 174 } 175 176 int32_t 177 UnixSignals::GetNextSignalNumber (int32_t current_signal) const 178 { 179 collection::const_iterator pos = m_signals.find (current_signal); 180 collection::const_iterator end = m_signals.end(); 181 if (pos == end) 182 return LLDB_INVALID_SIGNAL_NUMBER; 183 else 184 { 185 pos++; 186 if (pos == end) 187 return LLDB_INVALID_SIGNAL_NUMBER; 188 else 189 return (*pos).first; 190 } 191 } 192 193 const char * 194 UnixSignals::GetSignalInfo 195 ( 196 int32_t signo, 197 bool &should_suppress, 198 bool &should_stop, 199 bool &should_notify 200 ) const 201 { 202 collection::const_iterator pos = m_signals.find (signo); 203 if (pos == m_signals.end()) 204 return NULL; 205 else 206 { 207 const Signal &signal = (*pos).second; 208 should_suppress = signal.m_conditions[Signal::eCondSuppress]; 209 should_stop = signal.m_conditions[Signal::eCondStop]; 210 should_notify = signal.m_conditions[Signal::eCondNotify]; 211 return signal.m_name.AsCString(""); 212 } 213 } 214 215 bool 216 UnixSignals::GetCondition 217 ( 218 int32_t signo, 219 UnixSignals::Signal::Condition cond_pos 220 ) const 221 { 222 collection::const_iterator pos = m_signals.find (signo); 223 if (pos == m_signals.end()) 224 return false; 225 else 226 return (*pos).second.m_conditions[cond_pos]; 227 } 228 229 bool 230 UnixSignals::SetCondition (int32_t signo, UnixSignals::Signal::Condition cond_pos, bool value) 231 { 232 collection::iterator pos = m_signals.find (signo); 233 if (pos == m_signals.end()) 234 return false; 235 else 236 { 237 bool ret_value = (*pos).second.m_conditions[cond_pos]; 238 (*pos).second.m_conditions[cond_pos] = value; 239 return ret_value; 240 } 241 } 242 243 bool 244 UnixSignals::SetCondition (const char *signal_name, UnixSignals::Signal::Condition cond_pos, bool value) 245 { 246 int32_t signo; 247 Signal *signal = GetSignalByName (signal_name, signo); 248 if (signal == NULL) 249 return false; 250 else 251 { 252 bool ret_value = signal->m_conditions[cond_pos]; 253 signal->m_conditions[cond_pos] = value; 254 return ret_value; 255 } 256 } 257 258 bool 259 UnixSignals::GetShouldSuppress (int signo) const 260 { 261 return GetCondition (signo, Signal::eCondSuppress); 262 } 263 264 bool 265 UnixSignals::SetShouldSuppress (int signo, bool value) 266 { 267 return SetCondition (signo, Signal::eCondSuppress, value); 268 } 269 270 bool 271 UnixSignals::SetShouldSuppress (const char *signal_name, bool value) 272 { 273 return SetCondition (signal_name, Signal::eCondSuppress, value); 274 } 275 276 bool 277 UnixSignals::GetShouldStop (int signo) const 278 { 279 return GetCondition (signo, Signal::eCondStop); 280 } 281 282 bool 283 UnixSignals::SetShouldStop (int signo, bool value) 284 { 285 return SetCondition (signo, Signal::eCondStop, value); 286 } 287 288 bool 289 UnixSignals::SetShouldStop (const char *signal_name, bool value) 290 { 291 return SetCondition (signal_name, Signal::eCondStop, value); 292 } 293 294 bool 295 UnixSignals::GetShouldNotify (int signo) const 296 { 297 return GetCondition (signo, Signal::eCondNotify); 298 } 299 300 bool 301 UnixSignals::SetShouldNotify (int signo, bool value) 302 { 303 return SetCondition (signo, Signal::eCondNotify, value); 304 } 305 306 bool 307 UnixSignals::SetShouldNotify (const char *signal_name, bool value) 308 { 309 return SetCondition (signal_name, Signal::eCondNotify, value); 310 } 311