2012年12月3日 星期一

Override signal action/handler的使用方式 in Linux

Linux process支援signal的機制,可以使用Linux command - "kill"去對某個process發送signal,
你也可以去捕捉想捕捉的signal,然後去override default signal action/handler...

如果想捕捉下面兩個signals,可以override它們的signal action function
(SIGKILL與SIGSTOP不能如此捕捉)

SIGSEGV - Core Invalid memory reference
SIGTERM - Term Termination signal



...

static void hdl (int sig, siginfo_t *siginfo, void *context)
{

        switch(sig){
                case SIGSEGV:
                        printf("SIGSEGV occurred: %d.\n", getpid());
                        break;
                case SIGTERM:
                        printf("SIGTERM occurred: %d.\n", getpid());
                        break;
                default:
                        printf("Unknown signal.\n");
        }
        exit(0);
}

int main(){
        struct sigaction act;
        memset (&act, '\0', sizeof(act));
        act.sa_sigaction = &hdl;
        act.sa_flags = SA_SIGINFO;

        if (sigaction(SIGSEGV, &act, NULL) < 0) {
                perror ("sigaction");
                return 1;
        }

        if (sigaction(SIGTERM, &act, NULL) < 0) {
                perror ("sigaction");
                return 1;
        }
       

        while(1){
                printf("Henbin main %d\n", getpid());
                sleep(1);
        }


        return 0;
}



另外也可以使用下列方式捕捉所有signal,然後去override signal handler.

...

void catcher(int sig)
{
    printf("catcher");
    switch (sig)
        {
          case SIGTERM:
                            printf("SIGTERM.\n");
                            signal(SIGTERM, catcher);
                            atexit(0);
           break;

        case SIGSEGV:
                         printf("SIGSEGV.\n");
                         signal(SIGSEGV, catcher);
                         atexit(0);
          break;
       }
  }


int main(){
        int index=5;
        void *p=NULL;
        struct sigaction act;

        memset (&act, '\0', sizeof(act));

        act.sa_handler = catcher;
        act.sa_flags    = 0;

        sigfillset(&(act.sa_mask));

        signal(SIGINT, SIG_IGN);//ignore this signal
        signal(SIGHUP, SIG_IGN);//ignore this signal

        sigaction( SIGTERM, &act, NULL );
        sigaction( SIGSEGV, &act, NULL );


        while(index--){
                printf("Henbin main %d\n", getpid());
                sleep(1);
        }
        printf("%d.\n", *((int*)p));

        return 0;
}






沒有留言: