Sunday, October 19, 2014

Unix Prog: abort function

1. System Definition:
 ubuntu@ip-172-31-23-227:~$ less /usr/include/stdlib.h  
 ......  
 /* Abort execution and generate a core-dump. */  
 extern void abort (void) __THROW __attribute__ ((__noreturn__));  
 ......  

Note: even if we catch the signal SIGABRT, abort function will still terminate the process.

2. Basic Example:
abort.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
 #include<signal.h>  
   
 void sig_abrt(int signo)  
 {  
  printf("Catch the sig_abrt!\n");  
 }  
   
 int main(int argc, char* argv[])  
 {  
  if(signal(SIGABRT, sig_abrt) < 0) {  
   printf("signal error!\n");  
   exit(1);  
  }  
   
  kill(getpid(), SIGABRT);  
  printf("Returned from sig_abrt handler!\n");  
  exit(0);  
 }  

shell:
After catching the SIGABRT, sig_abrt get executed, and then it return back to main process without terminating the process.
 ubuntu@ip-172-31-23-227:~$ ./abort.out  
 Catch the sig_abrt!  
 Returned from sig_abrt handler!  

=====================================================================
abort.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
 #include<signal.h>  
   
 void sig_abrt(int signo)  
 {  
  printf("Catch the sig_abrt!\n");  
 }  
   
 int main(int argc, char* argv[])  
 {  
  if(signal(SIGABRT, sig_abrt) < 0) {  
   printf("signal error!\n");  
   exit(1);  
  }  
   
  abort();  
  printf("Returned from sig_abrt handler!\n");  
  exit(0);  
 }  

shell:
After calling the abort function, the process catches the SIGABRT, but after returning from signal handler, abort function just terminates the process.
 ubuntu@ip-172-31-23-227:~$ ./abort.out  
 Catch the sig_abrt!  
 Aborted (core dumped)  

3. one abort implementation
abort.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
 #include<signal.h>  
   
 void my_abort(void)  
 {  
  sigset_t mask;  
  struct sigaction action;  
   
  // Setup the SIGABRT handler to SIG_DFL  
  sigaction(SIGABRT, NULL, &action);  
  if(action.sa_handler == SIG_IGN) {  
   action.sa_handler == SIG_DFL;  
   sigaction(SIGABRT, &action, NULL);  
  }  
   
  if(action.sa_handler == SIG_DFL)  
   fflush(NULL); // flush out all io stream  
   
  // unblock the SIGABRT signal  
  sigfillset(&mask);  
  sigdelset(&mask, SIGABRT);  
  sigprocmask(SIG_SETMASK, &mask, NULL);  
   
  // Since we already setup the SIGABRT handler to be SIG_DFL  
  // So following call will terminate the process  
  kill(getpid(), SIGABRT);  
   
  // If we are here, then current system doesn't terminate process  
  // for default handler of SIGABRT  
  // Then we are going to unblock the mask, send SIGABRT signal again  
  // and then terminate the process manually  
  fflush(NULL); // flush out all io stream  
  action.sa_handler = SIG_DFL;  
  sigaction(SIGABRT, &action, NULL);  
  sigprocmask(SIG_SETMASK, &mask, NULL);  
  kill(getpid(), SIGABRT);  
  exit(1);  
 }  
   
 int main(int argc, char* argv[])  
 {  
  printf("before calling the abort()\n");  
  my_abort();  
  printf("after calling the abort()\n");  
 }  

shell:
After calling my_abort, it doesn't return to the main program.
 ubuntu@ip-172-31-23-227:~$ ./abort.out  
 before calling the abort()  
 Aborted (core dumped)  

No comments:

Post a Comment