Linux 下程序崩溃的信号捕获类

#ifndef SIGNALDBGER_H
#define SIGNALDBGER_H
 
 
void action(int signum);
 
#define Perror(s)       { \
                    printf("Line %d: %s: Error %d: %s\n", \
                        __LINE__, s, errno, \
                        strerror(errno)); \
                    exit(errno); \
                }
 
void action(int signum);
void Exit(int exit_val, void *on_exit_val);
 
class SignalDbger {
public:
    SignalDbger();
    static void   initial();
protected:
    ~SignalDbger();
public:
    // Signal Handler
    static void   sigAlrm(int s);
    static void   sigSegv(int s);
    static void   sigBus(int s);
    static void   sigInt(int s);
    static void   sigAbrt(int s);
    // Shudown Implementation later...
    //void   shutdown(int s);
    //void   dummyShutdown(int s); // dummy routine
 
 protected:
    static struct sigaction sigint_act, sigabrt_act;
    static struct sigaction sigalrm_act, sigsegv_act, sigbus_act;
    static struct sigaction oldact, oldalrm_act, oldbus_act, oldsegv_act;
 
    static SignalDbger *theThis;
 
    // Shudown Implementation later...
    // PDSigShutDownFunction shutDownFunction;
 
};
 
#endif // SIGNALDBGER_H


///// Test 
void main()
{     
    SignalDbger::initial();
}

#include "signaldbger.h"
#include        // exit
#include    /* sigaction */
#include     /* printf */
#include     /* errno */
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define VALUE_SZ 1024
#define NAME_SZ 1024
// static variable initialzation
SignalDbger *SignalDbger::theThis = 0;
typedef void (*PDDebugSig_handler) (int);
struct sigaction SignalDbger::sigint_act, SignalDbger::sigabrt_act;
struct sigaction SignalDbger::sigalrm_act, SignalDbger::sigsegv_act, SignalDbger::sigbus_act;
struct sigaction SignalDbger::oldact, SignalDbger::oldalrm_act, SignalDbger::oldbus_act, SignalDbger::oldsegv_act;
void action(int signum);
void SignalDbger::initial()
{
   if(theThis==0)
   {
      theThis = new SignalDbger();
   }
   // need to install exception handlers early to catch critical errors during init
   memset( &sigsegv_act,  0,  sizeof(sigsegv_act) );
   memset( &sigbus_act,   0,  sizeof(sigbus_act) );
   memset( &sigint_act,   0,  sizeof(sigint_act) );
   memset( &sigabrt_act,  0,  sizeof(sigabrt_act) );
   memset( &sigalrm_act,  0,  sizeof(sigalrm_act) );
   memset( &oldact,       0,  sizeof(oldact) );
   // install interrupt handler for SIGSEGV
   sigsegv_act.sa_handler = sigSegv ;
   sigemptyset( &sigsegv_act.sa_mask );
   sigsegv_act.sa_flags |= SA_RESTART ;
   sigaction(SIGSEGV, &sigsegv_act, &oldsegv_act );
   // install interrupt handler for SIGBUS
   sigbus_act.sa_handler = sigBus ;
   sigemptyset( &sigbus_act.sa_mask );
   sigbus_act.sa_flags |= SA_RESTART ;
   sigaction(SIGBUS, &sigbus_act, &oldbus_act );
   // install interrupt handler for SIGINT
   sigint_act.sa_handler = sigInt ;
   sigemptyset( &sigint_act.sa_mask );
   sigint_act.sa_flags |= SA_RESTART ;
   sigaction(SIGINT, &sigint_act, &oldact );
   // install interrupt handler for SIGABRT
   sigabrt_act.sa_handler = sigAbrt ;
   sigemptyset( &sigabrt_act.sa_mask );
   sigabrt_act.sa_flags |= SA_RESTART ;
   sigaction(SIGABRT, &sigabrt_act, &oldact );
   // install interrupt handler for SIGALRM
   sigalrm_act.sa_handler = sigAlrm ;
   sigemptyset( &sigalrm_act.sa_mask );
   sigalrm_act.sa_flags |= SA_RESTART ;
   sigaction(SIGALRM, &sigalrm_act, &oldalrm_act );
   int i;
   struct sigaction act, oldact;
   //if(on_exit(Exit, "test") == EOF)
     //  Perror("on_exit");
   act.sa_handler = action;
   act.sa_flags = SA_RESTART;  /* rearm */
   act.sa_mask = (sigset_t) {0};
   for(i = 1; i < 31; i++)
   {
       if(i == 9 || i == 19 || i == SIGSEGV || i== SIGINT || i == SIGABRT || i == SIGALRM || i == SIGBUS )
           continue;
       if( sigaction(i, &act, &oldact) == EOF )
           Perror("sigaction");
   }
}
void procClearShareMemory()
{
    QString _uniqueKey = "supermask.com";
    QSharedMemory sharedMemory;
    sharedMemory.setKey(_uniqueKey);
    if (sharedMemory.attach())
    {
        qDebug("%s receiveMessage MyApp dbx0", __FILE__);
        //_isRunning = true;
    }
}
void SignalDbger::sigAlrm(int s)
{  // signal Handler: should run in main thread!
   //if(shutdownInProgress)
   {
      char buf[VALUE_SZ];
      sprintf( buf, "echo \"ALARM: begin trace\"; pstack %d | c++filt; echo \"ALARM: end trace\"", getpid() );
      //cerr << "ALARM" << endl;
      system( buf );
      // restore default handler for SIGALRM and reset alarm
      sigaction(SIGALRM, &oldalrm_act, &oldact );
      alarm(1);
      procClearShareMemory();
  }
}
void SignalDbger::sigSegv(int s)
{  // signal Handler: should run in main thread!
      char buf[VALUE_SZ];  // length of string you put in buf below shouldn't exceed VALUE_SZ
      char domainName[NAME_SZ];
      char hostName[NAME_SZ];
      sprintf( buf, "pstack %d | c++filt > /tmp/pstack.out; echo \"SIGSEGV: begin trace\"; cat /tmp/pstack.out; echo \"SIGSEGV: end trace\"", getpid() );
      system( buf );
      // get domain and host name (have to get it just in case nothing is initialized at this time)
      //sysinfo(SI_SRPC_DOMAIN, domainName, sizeof(domainName));
      //sysinfo(SI_HOSTNAME, hostName, sizeof(hostName));
      // only send out mail if at PDI and running on a tool
      //if( 0==strcmp(domainName, "photon") && 0==strncmp( hostName, "ac", 2) )
      {
         sprintf( buf, "cat /tmp/pstack.out | Mail -s \"SIGSEGV on  on `date`\" [email protected]");//, hostName );
         system( buf );
      }
      // restore default handler for SIGSEGV and send signal out again
      sigaction(SIGSEGV, &oldsegv_act, &oldact );
      //sigsend(P_PID, getpid(), s);  // s should be SIGSEGV
      procClearShareMemory();
}
void SignalDbger::sigBus(int s)
{  // signal Handler: should run in main thread!
      char buf[VALUE_SZ]; // length of string you put in buf below shouldn't exceed VALUE_SZ
      char domainName[NAME_SZ];
      char hostName[NAME_SZ];
      sprintf( buf, "pstack %d | c++filt > /tmp/pstack.out; echo \"SIGBUS: begin trace\"; cat /tmp/pstack.out; echo \"SIGBUS: end trace\"", getpid() );
      system( buf );
      // get domain and host name (have to get it just in case nothing is initialized at this time)
      //sysinfo(SI_SRPC_DOMAIN, domainName, sizeof(domainName));
      //sysinfo(SI_HOSTNAME, hostName, sizeof(hostName));
      // only send out mail if at PDI and running on a tool
      //if( 0==strcmp(domainName, "photon") && 0==strncmp( hostName, "ac", 2) )
      {
      sprintf( buf, "cat /tmp/pstack.out | Mail -s \"SIGBUS on %s on `date`\" [email protected]");//, hostName );
      system( buf );
      }
      // flush log
      //pPool->dump();
      // restore default handler for SIGBUS and send signal out again
      sigaction(SIGBUS, &oldbus_act, &oldact );
      //sigsend(P_PID, getpid(), s);  // s should be SIGBUS
      procClearShareMemory();
}
void  SignalDbger::sigInt(int s)
{  // signal Handler: should run in main thread!
      char buf[VALUE_SZ];
      sprintf( buf, "echo \"SIGINT: begin trace\"; pstack %d | c++filt; echo \"SIGINT: end trace\"", getpid() );
      //cerr << "SIGINT" << endl;
      system( buf );
      procClearShareMemory();
}
void SignalDbger::sigAbrt(int s)
{  // signal Handler: should run in main thread!
      char buf[VALUE_SZ]; // length of string you put in buf below shouldn't exceed VALUE_SZ
      char domainName[NAME_SZ];
      char hostName[NAME_SZ];
      sprintf( buf, "pstack %d | c++filt > /tmp/pstack.out; echo \"SIGABRT: begin trace\"; cat /tmp/pstack.out; echo \"SIGABRT: end trace\"", getpid() );
      system( buf );
      // get domain and host name (have to get it just in case nothing is initialized at this time)
      //sysinfo(SI_SRPC_DOMAIN, domainName, sizeof(domainName));
      //sysinfo(SI_HOSTNAME, hostName, sizeof(hostName));
      // only send out mail if at PDI and running on a tool
      //if( 0==strcmp(domainName, "photon") && 0==strncmp( hostName, "ac", 2) )
      {
      sprintf( buf, "cat /tmp/pstack.out | Mail -s \"SIGABRT on  on `date`\" [email protected]");//, hostName );
      system( buf );
      }
      procClearShareMemory();
}
SignalDbger::SignalDbger()
{
}
int test_main(int argc, char *argv[])
{
    int i;
    struct sigaction act, oldact;
    //if(on_exit(Exit, "test") == EOF)
      //  Perror("on_exit");
    act.sa_handler = action;
    act.sa_flags = SA_RESTART;  /* rearm */
    act.sa_mask = (sigset_t) {0};
    for(i = 1; i < 31; i++) {
        if(i == 9 || i == 19)
            continue;
        if( sigaction(i, &act, &oldact) == EOF )
            Perror("sigaction");
    }
    printf("ok\n");
    while(1);
    exit(1);
}
void action(int signum)
{
    switch(signum) {
        case SIGHUP:
        case SIGQUIT:
        case SIGILL:
        case SIGTRAP:
        case SIGIOT:
        case SIGFPE:
        case SIGKILL:
        case SIGUSR1:
        case SIGUSR2:
        case SIGPIPE:
        case SIGTERM:
        case SIGCHLD:
        case SIGCONT:
        case SIGSTOP:
        case SIGTSTP:
        case SIGTTIN:
        case SIGTTOU:
        case SIGURG:
        case SIGXCPU:
        case SIGXFSZ:
        case SIGVTALRM:
        case SIGPROF:
        case SIGWINCH:
        case SIGIO:
        case SIGPWR:
            // printf("\nSIGPWR\n"); break;
            procClearShareMemory();
            break;
        //default:    printf("\nunknown signal %d\n", signum); break;
    }
}
void Exit(int exit_val, void *on_exit_val)
{
    printf("%d\n", exit_val);
}

 

你可能感兴趣的:(Qt)