diff options
Diffstat (limited to 'lldb/source/Target/UnixSignals.cpp')
-rw-r--r-- | lldb/source/Target/UnixSignals.cpp | 310 |
1 files changed, 310 insertions, 0 deletions
diff --git a/lldb/source/Target/UnixSignals.cpp b/lldb/source/Target/UnixSignals.cpp new file mode 100644 index 00000000000..e6500c5dba8 --- /dev/null +++ b/lldb/source/Target/UnixSignals.cpp @@ -0,0 +1,310 @@ +//===-- 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 + +using namespace lldb_private; + +UnixSignals::Signal::Signal (const char *name, bool default_suppress, bool default_stop, bool default_notify) : + m_name (name), + m_conditions () +{ + m_conditions[Signal::eCondSuppress] = default_suppress; + m_conditions[Signal::eCondStop] = default_stop; + m_conditions[Signal::eCondNotify] = default_notify; +} + +//---------------------------------------------------------------------- +// 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(); + + AddSignal(1, "SIGHUP", false, true, true ); // 1 hangup + AddSignal(2, "SIGINT", true, true, true ); // 2 interrupt + AddSignal(3, "SIGQUIT", false, true, true ); // 3 quit + AddSignal(4, "SIGILL", false, true, true ); // 4 illegal instruction (not reset when caught) + AddSignal(5, "SIGTRAP", true, true, true ); // 5 trace trap (not reset when caught) + AddSignal(6, "SIGABRT", false, true, true ); // 6 abort() + AddSignal(7, "SIGEMT", false, true, true ); // 7 pollable event ([XSR] generated, not supported) + AddSignal(8, "SIGFPE", false, true, true ); // 8 floating point exception + AddSignal(9, "SIGKILL", false, true, true ); // 9 kill (cannot be caught or ignored) + AddSignal(10, "SIGBUS", false, true, true ); // 10 bus error + AddSignal(11, "SIGSEGV", false, true, true ); // 11 segmentation violation + AddSignal(12, "SIGSYS", false, true, true ); // 12 bad argument to system call + AddSignal(13, "SIGPIPE", false, true, true ); // 13 write on a pipe with no one to read it + AddSignal(14, "SIGALRM", false, false, true ); // 14 alarm clock + AddSignal(15, "SIGTERM", false, true, true ); // 15 software termination signal from kill + AddSignal(16, "SIGURG", false, false, false); // 16 urgent condition on IO channel + AddSignal(17, "SIGSTOP", false, true, true ); // 17 sendable stop signal not from tty + AddSignal(18, "SIGTSTP", false, true, true ); // 18 stop signal from tty + AddSignal(19, "SIGCONT", false, true, true ); // 19 continue a stopped process + AddSignal(20, "SIGCHLD", false, false, true ); // 20 to parent on child stop or exit + AddSignal(21, "SIGTTIN", false, true, true ); // 21 to readers pgrp upon background tty read + AddSignal(22, "SIGTTOU", false, true, true ); // 22 like TTIN for output if (tp->t_local<OSTOP) + AddSignal(23, "SIGIO", false, false, false); // 23 input/output possible signal + AddSignal(24, "SIGXCPU", false, true, true ); // 24 exceeded CPU time limit + AddSignal(25, "SIGXFSZ", false, true, true ); // 25 exceeded file size limit + AddSignal(26, "SIGVTALRM", false, false, false); // 26 virtual time alarm + AddSignal(27, "SIGPROF", false, false, false); // 27 profiling time alarm + AddSignal(28, "SIGWINCH", false, false, false); // 28 window size changes + AddSignal(29, "SIGINFO", false, true, true ); // 29 information request + AddSignal(30, "SIGUSR1", false, true, true ); // 30 user defined signal 1 + AddSignal(31, "SIGUSR2", false, true, true ); // 31 user defined signal 2 +} +void +UnixSignals::AddSignal (int signo, const char *name, bool default_suppress, bool default_stop, bool default_notify) +{ + collection::iterator iter = m_signals.find (signo); + struct Signal new_signal (name, default_suppress, default_stop, default_notify); + + if (iter != m_signals.end()) + m_signals.erase (iter); + + m_signals.insert (iter, collection::value_type (signo, new_signal)); +} + +void +UnixSignals::RemoveSignal (int signo) +{ + collection::iterator pos = m_signals.find (signo); + if (pos != m_signals.end()) + m_signals.erase (pos); +} + +UnixSignals::Signal * +UnixSignals::GetSignalByName (const char *name, int32_t &signo) +{ + ConstString const_name (name); + + collection::iterator pos, end = m_signals.end (); + for (pos = m_signals.begin (); pos != end; pos++) + { + if (const_name == (*pos).second.m_name) + { + signo = (*pos).first; + return &((*pos).second); + } + } + return NULL; +} + + +const UnixSignals::Signal * +UnixSignals::GetSignalByName (const char *name, int32_t &signo) 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) + { + signo = (*pos).first; + return &((*pos).second); + } + } + return NULL; +} + +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 +{ + int32_t signo; + const Signal *signal = GetSignalByName (name, signo); + if (signal == NULL) + return LLDB_INVALID_SIGNAL_NUMBER; + else + return signo; +} + +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_conditions[Signal::eCondSuppress]; + should_stop = signal.m_conditions[Signal::eCondStop]; + should_notify = signal.m_conditions[Signal::eCondNotify]; + return signal.m_name.AsCString(""); + } +} + +bool +UnixSignals::GetCondition +( + int32_t signo, + UnixSignals::Signal::Condition cond_pos +) const +{ + collection::const_iterator pos = m_signals.find (signo); + if (pos == m_signals.end()) + return false; + else + return (*pos).second.m_conditions[cond_pos]; +} + +bool +UnixSignals::SetCondition (int32_t signo, UnixSignals::Signal::Condition cond_pos, bool value) +{ + collection::iterator pos = m_signals.find (signo); + if (pos == m_signals.end()) + return false; + else + { + bool ret_value = (*pos).second.m_conditions[cond_pos]; + (*pos).second.m_conditions[cond_pos] = value; + return ret_value; + } +} + +bool +UnixSignals::SetCondition (const char *signal_name, UnixSignals::Signal::Condition cond_pos, bool value) +{ + int32_t signo; + Signal *signal = GetSignalByName (signal_name, signo); + if (signal == NULL) + return false; + else + { + bool ret_value = signal->m_conditions[cond_pos]; + signal->m_conditions[cond_pos] = value; + return ret_value; + } +} + +bool +UnixSignals::GetShouldSuppress (int signo) const +{ + return GetCondition (signo, Signal::eCondSuppress); +} + +bool +UnixSignals::SetShouldSuppress (int signo, bool value) +{ + return SetCondition (signo, Signal::eCondSuppress, value); +} + +bool +UnixSignals::SetShouldSuppress (const char *signal_name, bool value) +{ + return SetCondition (signal_name, Signal::eCondSuppress, value); +} + +bool +UnixSignals::GetShouldStop (int signo) const +{ + return GetCondition (signo, Signal::eCondStop); +} + +bool +UnixSignals::SetShouldStop (int signo, bool value) +{ + return SetCondition (signo, Signal::eCondStop, value); +} + +bool +UnixSignals::SetShouldStop (const char *signal_name, bool value) +{ + return SetCondition (signal_name, Signal::eCondStop, value); +} + +bool +UnixSignals::GetShouldNotify (int signo) const +{ + return GetCondition (signo, Signal::eCondNotify); +} + +bool +UnixSignals::SetShouldNotify (int signo, bool value) +{ + return SetCondition (signo, Signal::eCondNotify, value); +} + +bool +UnixSignals::SetShouldNotify (const char *signal_name, bool value) +{ + return SetCondition (signal_name, Signal::eCondNotify, value); +} |