#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); } |