Ticket #11110: 0001-Add-support-for-real-time-signal-0-handling.patch

File 0001-Add-support-for-real-time-signal-0-handling.patch, 17.2 KB (added by beirdo, 12 years ago)
  • mythtv/libs/libmythbase/signalhandling.cpp

    From a9879b9260948c60e1a74f6f7119095f757d7334 Mon Sep 17 00:00:00 2001
    From: Gavin Hurlbut <ghurlbut@mythtv.org>
    Date: Sat, 22 Sep 2012 01:41:32 -0700
    Subject: [PATCH] Add support for real time signal 0 handling
    
    Fixes #11110
    
    Seems that some setups (in particular Ubuntu 12.04) are seeing our applications
    getting killed by SIGRTMIN.  As I have no clue what is causing this, I am
    changing the signal handling to use sigaction's extended handlers that hand
    off siginfo_t as well.  This gives us the source of the signal.
    
    Additionally, I added a default handler for SIGRTMIN.  This should end that
    nuisance.
    ---
     mythtv/libs/libmythbase/signalhandling.cpp  |   84 +++++++++++++++++++++------
     mythtv/libs/libmythbase/signalhandling.h    |   12 +++-
     mythtv/programs/mythavtest/main.cpp         |    2 +-
     mythtv/programs/mythbackend/main.cpp        |    2 +-
     mythtv/programs/mythccextractor/main.cpp    |    2 +-
     mythtv/programs/mythcommflag/main.cpp       |    2 +-
     mythtv/programs/mythfilldatabase/main.cpp   |    2 +-
     mythtv/programs/mythfrontend/main.cpp       |    2 +-
     mythtv/programs/mythjobqueue/main.cpp       |    2 +-
     mythtv/programs/mythlcdserver/main.cpp      |    2 +-
     mythtv/programs/mythlogserver/main.cpp      |    2 +-
     mythtv/programs/mythmediaserver/main.cpp    |    2 +-
     mythtv/programs/mythmetadatalookup/main.cpp |    2 +-
     mythtv/programs/mythpreviewgen/main.cpp     |    2 +-
     mythtv/programs/mythshutdown/main.cpp       |    2 +-
     mythtv/programs/mythtranscode/main.cpp      |    2 +-
     mythtv/programs/mythtv-setup/main.cpp       |    2 +-
     mythtv/programs/mythutil/main.cpp           |    2 +-
     mythtv/programs/mythwelcome/main.cpp        |    2 +-
     19 files changed, 91 insertions(+), 39 deletions(-)
    
    diff --git a/mythtv/libs/libmythbase/signalhandling.cpp b/mythtv/libs/libmythbase/signalhandling.cpp
    index aae4aef..616693d 100644
    a b SignalHandler::SignalHandler(QList<int> &signallist, QObject *parent) : 
    6363    s_exit_program = false; // set here due to "C++ static initializer madness"
    6464    sig_str_init();
    6565
     66    m_sigStack = new char[SIGSTKSZ];
     67    stack_t stack;
     68    stack.ss_sp = (void *)m_sigStack;
     69    stack.ss_flags = 0;
     70    stack.ss_size = SIGSTKSZ;
     71
     72    // Carry on without the signal stack if it fails
     73    if (sigaltstack(&stack, NULL) == -1)
     74    {
     75        cerr << "Couldn't create signal stack!" << endl;
     76        delete [] m_sigStack;
     77        m_sigStack = NULL;
     78    }
     79
    6680    if (s_defaultHandlerList.isEmpty())
    6781        s_defaultHandlerList << SIGINT << SIGTERM << SIGSEGV << SIGABRT
    6882#ifndef _WIN32
    6983                             << SIGBUS
    7084#endif
    71                              << SIGFPE << SIGILL;
     85                             << SIGFPE << SIGILL << SIGRTMIN;
    7286
    7387#ifndef _WIN32
    7488    if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sigFd))
    SignalHandler::~SignalHandler() 
    107121    }
    108122
    109123    QMutexLocker locker(&m_sigMapLock);
    110     QMap<int, void (*)(void)>::iterator it = m_sigMap.begin();
     124    QMap<int, SigHandlerFunc>::iterator it = m_sigMap.begin();
    111125    for ( ; it != m_sigMap.end(); ++it)
    112126    {
    113127        int signum = it.key();
    void SignalHandler::Done(void) 
    133147}
    134148
    135149
    136 void SignalHandler::SetHandler(int signum, void (*handler)(void))
     150void SignalHandler::SetHandler(int signum, SigHandlerFunc handler)
    137151{
    138152    QMutexLocker locker(&s_singletonLock);
    139153    if (s_singleton)
    140154        s_singleton->SetHandlerPrivate(signum, handler);
    141155}
    142156
    143 void SignalHandler::SetHandlerPrivate(int signum, void (*handler)(void))
     157void SignalHandler::SetHandlerPrivate(int signum, SigHandlerFunc handler)
    144158{
    145159#ifndef _WIN32
    146160    const char *signame = strsignal(signum);
    void SignalHandler::SetHandlerPrivate(int signum, void (*handler)(void)) 
    163177    if (!sa_handler_already_set)
    164178    {
    165179        struct sigaction sa;
    166         sa.sa_handler = SignalHandler::signalHandler;
     180        sa.sa_sigaction = SignalHandler::signalHandler;
    167181        sigemptyset(&sa.sa_mask);
    168         sa.sa_flags = SA_RESTART;
     182        sa.sa_flags = SA_RESTART | SA_SIGINFO;
     183        if (m_sigStack)
     184            sa.sa_flags |= SA_ONSTACK;
    169185
    170186        sig_str_init(signum, qPrintable(signal_name));
    171187
    void SignalHandler::SetHandlerPrivate(int signum, void (*handler)(void)) 
    176192#endif
    177193}
    178194
    179 void SignalHandler::signalHandler(int signum)
     195typedef struct {
     196    int signum;
     197    int code;
     198    int pid;
     199    int uid;
     200    uint64_t value;
     201} SignalInfo;
     202
     203void SignalHandler::signalHandler(int signum, siginfo_t *info, void *context)
    180204{
    181     char a = (char)signum;
     205    SignalInfo signalInfo;
     206
     207    (void)context;
     208    signalInfo.signum = signum;
     209    signalInfo.code   = (info ? info->si_code : 0);
     210    signalInfo.pid    = (info ? (int)info->si_pid : 0);
     211    signalInfo.uid    = (info ? (int)info->si_uid : 0);
     212    signalInfo.value  = (info ? (uint64_t)info->si_ptr : 0);
    182213
    183214    // Keep trying if there's no room to write, but stop on error (-1)
    184     while (::write(sigFd[0], &a, 1) == 0);
     215    int index = 0;
     216    int size  = sizeof(SignalInfo);
     217    char *buffer = (char *)&signalInfo;
     218    do {
     219        int written = ::write(sigFd[0], &buffer[index], size);
     220        // If there's an error, the signal will not be seen be the application,
     221        // but we can't keep trying.
     222        if (written < 0)
     223            break;
     224        index += written;
     225        size  -= written;
     226    } while (size > 0);
    185227
    186228    // One must not return from SEGV, ILL, BUS or FPE. When these
    187229    // are raised by the program itself they will immediately get
    void SignalHandler::handleSignal(void) 
    237279#ifndef _WIN32
    238280    m_notifier->setEnabled(false);
    239281
    240     char a;
    241     int ret = ::read(sigFd[1], &a, sizeof(a));
    242     int signum = (int)a;
    243     (void)ret;
     282    SignalInfo signalInfo;
     283    int ret = ::read(sigFd[1], &signalInfo, sizeof(SignalInfo));
     284    bool infoComplete = (ret == sizeof(SignalInfo));
     285    int signum = (infoComplete ? signalInfo.signum : 0);
    244286
    245     const char *signame = strsignal(signum);
    246     signame = strdup(signame ? signame : "Unknown");
    247     LOG(VB_GENERAL, LOG_CRIT, QString("Received %1").arg(signame));
    248     free((void *)signame);
     287    if (infoComplete)
     288    {
     289        const char *signame = strsignal(signum);
     290        signame = strdup(signame ? signame : "Unknown Signal");
     291        LOG(VB_GENERAL, LOG_CRIT,
     292            QString("Received %1: Code %2, PID %3, UID %4, Value 0x%5")
     293            .arg(signame) .arg(signalInfo.code) .arg(signalInfo.pid)
     294            .arg(signalInfo.uid) .arg(signalInfo.value,8,16,QChar('0')));
     295        free((void *)signame);
     296    }
    249297
    250     void (*handler)(void) = NULL;
     298    SigHandlerFunc handler = NULL;
    251299
    252300    switch (signum)
    253301    {
  • mythtv/libs/libmythbase/signalhandling.h

    diff --git a/mythtv/libs/libmythbase/signalhandling.h b/mythtv/libs/libmythbase/signalhandling.h
    index 73f96a7..5d39d01 100644
    a b  
    1414#include "mythbaseexp.h"  //  MBASE_PUBLIC , etc.
    1515#include "mthread.h"
    1616
     17typedef void (*SigHandlerFunc)(void);
     18
    1719/// \brief A container object to handle UNIX signals in the Qt space correctly
    1820class MBASE_PUBLIC SignalHandler: public QObject
    1921{
    class MBASE_PUBLIC SignalHandler: public QObject 
    2325    static void Init(QList<int> &signallist, QObject *parent = NULL);
    2426    static void Done(void);
    2527
    26     static void SetHandler(int signal, void (*handler)(void));
     28    static void SetHandler(int signal, SigHandlerFunc handler);
    2729
    2830    static bool IsExiting(void) { return s_exit_program; }
    2931
    3032    // Unix signal handler.
    31     static void signalHandler(int signum);
     33    // context is of type ucontext_t * cast to void *
     34    static void signalHandler(int signum, siginfo_t *info, void *context);
    3235
    3336  public slots:
    3437    // Qt signal handler.
    class MBASE_PUBLIC SignalHandler: public QObject 
    3740  private:
    3841    SignalHandler(QList<int> &signallist, QObject *parent);
    3942    ~SignalHandler();
    40     void SetHandlerPrivate(int signal, void (*handler)(void));
     43    void SetHandlerPrivate(int signal, SigHandlerFunc handler);
    4144
    4245    static int sigFd[2];
    4346    static volatile bool s_exit_program;
    4447    QSocketNotifier *m_notifier;
     48    char *m_sigStack;
    4549
    4650    QMutex m_sigMapLock;
    47     QMap<int, void (*)(void)> m_sigMap;
     51    QMap<int, SigHandlerFunc> m_sigMap;
    4852    static QList<int> s_defaultHandlerList;
    4953
    5054    static QMutex s_singletonLock;
  • mythtv/programs/mythavtest/main.cpp

    diff --git a/mythtv/programs/mythavtest/main.cpp b/mythtv/programs/mythavtest/main.cpp
    index 9bf14c5..8ed2ba1 100644
    a b int main(int argc, char *argv[]) 
    232232#ifndef _WIN32
    233233    QList<int> signallist;
    234234    signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE
    235                << SIGILL;
     235               << SIGILL << SIGRTMIN;
    236236    SignalHandler::Init(signallist);
    237237    signal(SIGHUP, SIG_IGN);
    238238#endif
  • mythtv/programs/mythbackend/main.cpp

    diff --git a/mythtv/programs/mythbackend/main.cpp b/mythtv/programs/mythbackend/main.cpp
    index 3c508ca..22820bf 100644
    a b int main(int argc, char **argv) 
    103103#ifndef _WIN32
    104104    QList<int> signallist;
    105105    signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE
    106                << SIGILL;
     106               << SIGILL << SIGRTMIN;
    107107    SignalHandler::Init(signallist);
    108108    signal(SIGHUP, SIG_IGN);
    109109#endif
  • mythtv/programs/mythccextractor/main.cpp

    diff --git a/mythtv/programs/mythccextractor/main.cpp b/mythtv/programs/mythccextractor/main.cpp
    index a34b904..68272bd 100644
    a b int main(int argc, char *argv[]) 
    145145#ifndef _WIN32
    146146    QList<int> signallist;
    147147    signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE
    148                << SIGILL;
     148               << SIGILL << SIGRTMIN;
    149149    SignalHandler::Init(signallist);
    150150    signal(SIGHUP, SIG_IGN);
    151151#endif
  • mythtv/programs/mythcommflag/main.cpp

    diff --git a/mythtv/programs/mythcommflag/main.cpp b/mythtv/programs/mythcommflag/main.cpp
    index ba12406..5c03c1d 100644
    a b int main(int argc, char *argv[]) 
    11261126#ifndef _WIN32
    11271127    QList<int> signallist;
    11281128    signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE
    1129                << SIGILL;
     1129               << SIGILL << SIGRTMIN;
    11301130    SignalHandler::Init(signallist);
    11311131    signal(SIGHUP, SIG_IGN);
    11321132#endif
  • mythtv/programs/mythfilldatabase/main.cpp

    diff --git a/mythtv/programs/mythfilldatabase/main.cpp b/mythtv/programs/mythfilldatabase/main.cpp
    index a90381d..30c1352 100644
    a b int main(int argc, char *argv[]) 
    348348#ifndef _WIN32
    349349    QList<int> signallist;
    350350    signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE
    351                << SIGILL;
     351               << SIGILL << SIGRTMIN;
    352352    SignalHandler::Init(signallist);
    353353    signal(SIGHUP, SIG_IGN);
    354354#endif
  • mythtv/programs/mythfrontend/main.cpp

    diff --git a/mythtv/programs/mythfrontend/main.cpp b/mythtv/programs/mythfrontend/main.cpp
    index 0192097..9d91967 100644
    a b int main(int argc, char **argv) 
    14781478#ifndef _WIN32
    14791479    QList<int> signallist;
    14801480    signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE
    1481                << SIGILL;
     1481               << SIGILL << SIGRTMIN;
    14821482    SignalHandler::Init(signallist);
    14831483    SignalHandler::SetHandler(SIGUSR1, handleSIGUSR1);
    14841484    SignalHandler::SetHandler(SIGUSR2, handleSIGUSR2);
  • mythtv/programs/mythjobqueue/main.cpp

    diff --git a/mythtv/programs/mythjobqueue/main.cpp b/mythtv/programs/mythjobqueue/main.cpp
    index 1718808..bd9c638 100644
    a b int main(int argc, char *argv[]) 
    113113#ifndef _WIN32
    114114    QList<int> signallist;
    115115    signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE
    116                << SIGILL;
     116               << SIGILL << SIGRTMIN;
    117117    SignalHandler::Init(signallist);
    118118    signal(SIGHUP, SIG_IGN);
    119119#endif
  • mythtv/programs/mythlcdserver/main.cpp

    diff --git a/mythtv/programs/mythlcdserver/main.cpp b/mythtv/programs/mythlcdserver/main.cpp
    index f9d84e5..a211195 100644
    a b int main(int argc, char **argv) 
    100100#ifndef _WIN32
    101101    QList<int> signallist;
    102102    signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE
    103                << SIGILL;
     103               << SIGILL << SIGRTMIN;
    104104    SignalHandler::Init(signallist);
    105105    signal(SIGHUP, SIG_IGN);
    106106#endif
  • mythtv/programs/mythlogserver/main.cpp

    diff --git a/mythtv/programs/mythlogserver/main.cpp b/mythtv/programs/mythlogserver/main.cpp
    index f327c47..9d9ebca 100644
    a b int main(int argc, char *argv[]) 
    105105#ifndef _WIN32
    106106    QList<int> signallist;
    107107    signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE
    108                << SIGILL;
     108               << SIGILL << SIGRTMIN;
    109109    SignalHandler::Init(signallist);
    110110    SignalHandler::SetHandler(SIGHUP, logSigHup);
    111111#endif
  • mythtv/programs/mythmediaserver/main.cpp

    diff --git a/mythtv/programs/mythmediaserver/main.cpp b/mythtv/programs/mythmediaserver/main.cpp
    index 66e744b..756afd6 100644
    a b int main(int argc, char *argv[]) 
    111111#ifndef _WIN32
    112112    QList<int> signallist;
    113113    signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE
    114                << SIGILL;
     114               << SIGILL << SIGRTMIN;
    115115    SignalHandler::Init(signallist);
    116116    signal(SIGHUP, SIG_IGN);
    117117#endif
  • mythtv/programs/mythmetadatalookup/main.cpp

    diff --git a/mythtv/programs/mythmetadatalookup/main.cpp b/mythtv/programs/mythmetadatalookup/main.cpp
    index ed8f737..c18b030 100644
    a b int main(int argc, char *argv[]) 
    9191#ifndef _WIN32
    9292    QList<int> signallist;
    9393    signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE
    94                << SIGILL;
     94               << SIGILL << SIGRTMIN;
    9595    SignalHandler::Init(signallist);
    9696    signal(SIGHUP, SIG_IGN);
    9797#endif
  • mythtv/programs/mythpreviewgen/main.cpp

    diff --git a/mythtv/programs/mythpreviewgen/main.cpp b/mythtv/programs/mythpreviewgen/main.cpp
    index 388bacb..5c238e2 100644
    a b int main(int argc, char **argv) 
    206206#ifndef _WIN32
    207207    QList<int> signallist;
    208208    signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE
    209                << SIGILL;
     209               << SIGILL << SIGRTMIN;
    210210    SignalHandler::Init(signallist);
    211211    signal(SIGHUP, SIG_IGN);
    212212#endif
  • mythtv/programs/mythshutdown/main.cpp

    diff --git a/mythtv/programs/mythshutdown/main.cpp b/mythtv/programs/mythshutdown/main.cpp
    index 33fd682..1505924 100644
    a b int main(int argc, char **argv) 
    787787#ifndef _WIN32
    788788    QList<int> signallist;
    789789    signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE
    790                << SIGILL;
     790               << SIGILL << SIGRTMIN;
    791791    SignalHandler::Init(signallist);
    792792    signal(SIGHUP, SIG_IGN);
    793793#endif
  • mythtv/programs/mythtranscode/main.cpp

    diff --git a/mythtv/programs/mythtranscode/main.cpp b/mythtv/programs/mythtranscode/main.cpp
    index 0a08d39..49a1a7a 100644
    a b int main(int argc, char *argv[]) 
    377377#ifndef _WIN32
    378378    QList<int> signallist;
    379379    signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE
    380                << SIGILL;
     380               << SIGILL << SIGRTMIN;
    381381    SignalHandler::Init(signallist);
    382382    signal(SIGHUP, SIG_IGN);
    383383#endif
  • mythtv/programs/mythtv-setup/main.cpp

    diff --git a/mythtv/programs/mythtv-setup/main.cpp b/mythtv/programs/mythtv-setup/main.cpp
    index 36cd975..6313767 100644
    a b int main(int argc, char *argv[]) 
    287287#ifndef _WIN32
    288288    QList<int> signallist;
    289289    signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE
    290                << SIGILL;
     290               << SIGILL << SIGRTMIN;
    291291    SignalHandler::Init(signallist);
    292292    signal(SIGHUP, SIG_IGN);
    293293#endif
  • mythtv/programs/mythutil/main.cpp

    diff --git a/mythtv/programs/mythutil/main.cpp b/mythtv/programs/mythutil/main.cpp
    index 655d39a..1e6c4bb 100644
    a b int main(int argc, char *argv[]) 
    7979#ifndef _WIN32
    8080    QList<int> signallist;
    8181    signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE
    82                << SIGILL;
     82               << SIGILL << SIGRTMIN;
    8383    SignalHandler::Init(signallist);
    8484    signal(SIGHUP, SIG_IGN);
    8585#endif
  • mythtv/programs/mythwelcome/main.cpp

    diff --git a/mythtv/programs/mythwelcome/main.cpp b/mythtv/programs/mythwelcome/main.cpp
    index 8b925be..ee8fdf2 100644
    a b int main(int argc, char **argv) 
    7777#ifndef _WIN32
    7878    QList<int> signallist;
    7979    signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE
    80                << SIGILL;
     80               << SIGILL << SIGRTMIN;
    8181    SignalHandler::Init(signallist);
    8282    signal(SIGHUP, SIG_IGN);
    8383#endif