| //===-- UnixSignals.cpp -----------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "lldb/Target/UnixSignals.h" |
| |
| // C Includes |
| // C++ Includes |
| // Other libraries and framework includes |
| // Project includes |
| #include "lldb/Interpreter/Args.h" |
| |
| using namespace lldb_private; |
| |
| UnixSignals::Signal::Signal |
| ( |
| const char *name, |
| const char *short_name, |
| bool default_suppress, |
| bool default_stop, |
| bool default_notify, |
| const char *description |
| ) : |
| m_name (name), |
| m_short_name (short_name), |
| m_description (), |
| m_suppress (default_suppress), |
| m_stop (default_stop), |
| m_notify (default_notify) |
| { |
| if (description) |
| m_description.assign (description); |
| } |
| |
| //---------------------------------------------------------------------- |
| // UnixSignals constructor |
| //---------------------------------------------------------------------- |
| UnixSignals::UnixSignals () |
| { |
| Reset (); |
| } |
| |
| //---------------------------------------------------------------------- |
| // Destructor |
| //---------------------------------------------------------------------- |
| UnixSignals::~UnixSignals () |
| { |
| } |
| |
| void |
| UnixSignals::Reset () |
| { |
| // This builds one standard set of Unix Signals. If yours aren't quite in this |
| // order, you can either subclass this class, and use Add & Remove to change them |
| // or you can subclass and build them afresh in your constructor; |
| m_signals.clear(); |
| // SIGNO NAME SHORT NAME SUPPRESS STOP NOTIFY DESCRIPTION |
| // ====== ============ ========== ========= ====== ====== =================================================== |
| AddSignal (1, "SIGHUP", "HUP", false, true, true, "hangup"); |
| AddSignal (2, "SIGINT", "INT", true, true, true, "interrupt"); |
| AddSignal (3, "SIGQUIT", "QUIT", false, true, true, "quit"); |
| AddSignal (4, "SIGILL", "ILL", false, true, true, "illegal instruction"); |
| AddSignal (5, "SIGTRAP", "TRAP", true, true, true, "trace trap (not reset when caught)"); |
| AddSignal (6, "SIGABRT", "ABRT", false, true, true, "abort()"); |
| AddSignal (7, "SIGEMT", "EMT", false, true, true, "pollable event"); |
| AddSignal (8, "SIGFPE", "FPE", false, true, true, "floating point exception"); |
| AddSignal (9, "SIGKILL", "KILL", false, true, true, "kill"); |
| AddSignal (10, "SIGBUS", "BUS", false, true, true, "bus error"); |
| AddSignal (11, "SIGSEGV", "SEGV", false, true, true, "segmentation violation"); |
| AddSignal (12, "SIGSYS", "SYS", false, true, true, "bad argument to system call"); |
| AddSignal (13, "SIGPIPE", "PIPE", false, true, true, "write on a pipe with no one to read it"); |
| AddSignal (14, "SIGALRM", "ALRM", false, false, true, "alarm clock"); |
| AddSignal (15, "SIGTERM", "TERM", false, true, true, "software termination signal from kill"); |
| AddSignal (16, "SIGURG", "URG", false, false, false, "urgent condition on IO channel"); |
| AddSignal (17, "SIGSTOP", "STOP", false, true, true, "sendable stop signal not from tty"); |
| AddSignal (18, "SIGTSTP", "TSTP", false, true, true, "stop signal from tty"); |
| AddSignal (19, "SIGCONT", "CONT", false, true, true, "continue a stopped process"); |
| AddSignal (20, "SIGCHLD", "CHLD", false, false, true, "to parent on child stop or exit"); |
| AddSignal (21, "SIGTTIN", "TTIN", false, true, true, "to readers process group upon background tty read"); |
| AddSignal (22, "SIGTTOU", "TTOU", false, true, true, "to readers process group upon background tty write"); |
| AddSignal (23, "SIGIO", "IO", false, false, false, "input/output possible signal"); |
| AddSignal (24, "SIGXCPU", "XCPU", false, true, true, "exceeded CPU time limit"); |
| AddSignal (25, "SIGXFSZ", "XFSZ", false, true, true, "exceeded file size limit"); |
| AddSignal (26, "SIGVTALRM", "VTALRM", false, false, false, "virtual time alarm"); |
| AddSignal (27, "SIGPROF", "PROF", false, false, false, "profiling time alarm"); |
| AddSignal (28, "SIGWINCH", "WINCH", false, false, false, "window size changes"); |
| AddSignal (29, "SIGINFO", "INFO", false, true, true, "information request"); |
| AddSignal (30, "SIGUSR1", "USR1", false, true, true, "user defined signal 1"); |
| AddSignal (31, "SIGUSR2", "USR2", false, true, true, "user defined signal 2"); |
| } |
| |
| void |
| UnixSignals::AddSignal |
| ( |
| int signo, |
| const char *name, |
| const char *short_name, |
| bool default_suppress, |
| bool default_stop, |
| bool default_notify, |
| const char *description |
| ) |
| { |
| Signal new_signal (name, short_name, default_suppress, default_stop, default_notify, description); |
| m_signals.insert (std::make_pair(signo, new_signal)); |
| } |
| |
| void |
| UnixSignals::RemoveSignal (int signo) |
| { |
| collection::iterator pos = m_signals.find (signo); |
| if (pos != m_signals.end()) |
| m_signals.erase (pos); |
| } |
| |
| const char * |
| UnixSignals::GetSignalAsCString (int signo) const |
| { |
| collection::const_iterator pos = m_signals.find (signo); |
| if (pos == m_signals.end()) |
| return NULL; |
| else |
| return pos->second.m_name.GetCString (); |
| } |
| |
| |
| bool |
| UnixSignals::SignalIsValid (int32_t signo) const |
| { |
| return m_signals.find (signo) != m_signals.end(); |
| } |
| |
| |
| int32_t |
| UnixSignals::GetSignalNumberFromName (const char *name) const |
| { |
| ConstString const_name (name); |
| |
| collection::const_iterator pos, end = m_signals.end (); |
| for (pos = m_signals.begin (); pos != end; pos++) |
| { |
| if ((const_name == pos->second.m_name) || (const_name == pos->second.m_short_name)) |
| return pos->first; |
| } |
| |
| const int32_t signo = Args::StringToSInt32(name, LLDB_INVALID_SIGNAL_NUMBER, 0); |
| if (signo != LLDB_INVALID_SIGNAL_NUMBER) |
| return signo; |
| return LLDB_INVALID_SIGNAL_NUMBER; |
| } |
| |
| int32_t |
| UnixSignals::GetFirstSignalNumber () const |
| { |
| if (m_signals.empty()) |
| return LLDB_INVALID_SIGNAL_NUMBER; |
| |
| return (*m_signals.begin ()).first; |
| } |
| |
| int32_t |
| UnixSignals::GetNextSignalNumber (int32_t current_signal) const |
| { |
| collection::const_iterator pos = m_signals.find (current_signal); |
| collection::const_iterator end = m_signals.end(); |
| if (pos == end) |
| return LLDB_INVALID_SIGNAL_NUMBER; |
| else |
| { |
| pos++; |
| if (pos == end) |
| return LLDB_INVALID_SIGNAL_NUMBER; |
| else |
| return pos->first; |
| } |
| } |
| |
| const char * |
| UnixSignals::GetSignalInfo |
| ( |
| int32_t signo, |
| bool &should_suppress, |
| bool &should_stop, |
| bool &should_notify |
| ) const |
| { |
| collection::const_iterator pos = m_signals.find (signo); |
| if (pos == m_signals.end()) |
| return NULL; |
| else |
| { |
| const Signal &signal = pos->second; |
| should_suppress = signal.m_suppress; |
| should_stop = signal.m_stop; |
| should_notify = signal.m_notify; |
| return signal.m_name.AsCString(""); |
| } |
| } |
| |
| bool |
| UnixSignals::GetShouldSuppress (int signo) const |
| { |
| collection::const_iterator pos = m_signals.find (signo); |
| if (pos != m_signals.end()) |
| return pos->second.m_suppress; |
| return false; |
| } |
| |
| bool |
| UnixSignals::SetShouldSuppress (int signo, bool value) |
| { |
| collection::iterator pos = m_signals.find (signo); |
| if (pos != m_signals.end()) |
| { |
| pos->second.m_suppress = value; |
| return true; |
| } |
| return false; |
| } |
| |
| bool |
| UnixSignals::SetShouldSuppress (const char *signal_name, bool value) |
| { |
| const int32_t signo = GetSignalNumberFromName (signal_name); |
| if (signo != LLDB_INVALID_SIGNAL_NUMBER) |
| return SetShouldSuppress (signo, value); |
| return false; |
| } |
| |
| bool |
| UnixSignals::GetShouldStop (int signo) const |
| { |
| collection::const_iterator pos = m_signals.find (signo); |
| if (pos != m_signals.end()) |
| return pos->second.m_stop; |
| return false; |
| } |
| |
| bool |
| UnixSignals::SetShouldStop (int signo, bool value) |
| { |
| collection::iterator pos = m_signals.find (signo); |
| if (pos != m_signals.end()) |
| { |
| pos->second.m_stop = value; |
| return true; |
| } |
| return false; |
| } |
| |
| bool |
| UnixSignals::SetShouldStop (const char *signal_name, bool value) |
| { |
| const int32_t signo = GetSignalNumberFromName (signal_name); |
| if (signo != LLDB_INVALID_SIGNAL_NUMBER) |
| return SetShouldStop (signo, value); |
| return false; |
| } |
| |
| bool |
| UnixSignals::GetShouldNotify (int signo) const |
| { |
| collection::const_iterator pos = m_signals.find (signo); |
| if (pos != m_signals.end()) |
| return pos->second.m_notify; |
| return false; |
| } |
| |
| bool |
| UnixSignals::SetShouldNotify (int signo, bool value) |
| { |
| collection::iterator pos = m_signals.find (signo); |
| if (pos != m_signals.end()) |
| { |
| pos->second.m_notify = value; |
| return true; |
| } |
| return false; |
| } |
| |
| bool |
| UnixSignals::SetShouldNotify (const char *signal_name, bool value) |
| { |
| const int32_t signo = GetSignalNumberFromName (signal_name); |
| if (signo != LLDB_INVALID_SIGNAL_NUMBER) |
| return SetShouldNotify (signo, value); |
| return false; |
| } |