blob: 1398639facdf7daad5648b812e650f4826fa986d [file] [log] [blame]
//===-- 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;
}