//===-- 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); }