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