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 <stdlib.h>       // exit
#include <signal.h>   /* sigaction */
#include <stdio.h>    /* printf */
#include <errno.h>    /* errno */
#include <iostream>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <sys/sysinfo.h>
#include <QSharedMemory>
#include <QString>
#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`\" hy-Exceptions@supermask.com");//, 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`\" hy-Exceptions@supermask.com");//, 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`\" hy-Exceptions@supermask.com");//, 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);
}

 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Qt程序崩溃异常捕获的方法: 1.使用qInstallMessageHandler()函数来自定义消息处理程序,以便在程序崩溃时获取相关信息。以下是一个示例代码: ```cpp void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) { QByteArray localMsg = msg.toLocal8Bit(); switch (type) { case QtDebugMsg: fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; case QtInfoMsg: fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; case QtWarningMsg: fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; case QtCriticalMsg: fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; case QtFatalMsg: fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); abort(); } } int main(int argc, char *argv[]) { qInstallMessageHandler(myMessageOutput); QApplication a(argc, argv); // ... return a.exec(); } ``` 2.使用Qt的调试器来捕获异常。在Qt Creator中,可以通过以下步骤来使用调试器: - 在Qt Creator中打开项目并设置断点。 - 单击“调试”按钮以启动调试器。 - 在调试器中运行程序并观察变量和堆栈。 - 如果程序崩溃,调试器将停止并显示崩溃信息。 3.使用第三方库来捕获异常,例如Google Breakpad。Google Breakpad是一个开源库,可用于在Windows、Linux和Mac OS X上捕获程序崩溃信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值