0

I am using signal handler for ctrl-c signal. i.e whenever ctrl-c signal is generated instead of exiting the application I do some action.

Let us suppose if my application hangs due to while(1) loop (any error condition) is it possible for me to exit application only in that case?

ex:

void handle()
{
    /*do some action*/
    ----
    ----
    ---

    if ( while(1) detected)
    {
    exit(0);
    }
}


main()
{
    struct sigaction myhandle; 
    myhandle.sa_handler = handle;
    sigemptyset(&myhandle.sa_mask);
    myhandle.sa_flags = 0;
    sigaction(SIGINT, &myhandle, NULL);

   while(1);
}

Thanks

Pavan Manjunath
  • 27,404
  • 12
  • 99
  • 125
user1225606
  • 1,123
  • 2
  • 14
  • 14
  • 1) The declaration/definition/signature for your signal handler is wrong, it should be `void handle(int signum);` 2: lookup `man 2 siglongjmp` – wildplasser Apr 20 '12 at 08:44

1 Answers1

0

Its very difficult to find whether your code was in an accidental infinite loop before you received a signal like Ctrl-C. I can suggest some heuristic approaches. Have a variable of sufficiently long size, preferably a global unsigned long long int, and keep incrementing this variable inside the loops that you suspect might slip into infinite loops on every iteration of the loop. Now, when you receive a signal, check for the value of this variable in the signal handler against a threshold MAX_NUMBER_OF_ITERATIONS. If the variable exceeds the user defined threshold then declare an infinite loop and exit else simply continue.

Something on these lines-

#define MAX_NUMBER_OF_ITERATIONS 100000000

unsigned long long checkForEndlessLoop=0;
bool overflow;

void sigHandler (int signum)
{
   signal(sig, SIG_IGN); // Ignore it so that another Ctrl-C doesn't appear any soon
   if (overflow || (checkForEndlessLoop > MAX_NUMBER_OF_ITERATIONS) )
   {
      //Something's fishy in the loop.
      exit(0);
   }
   else
   {
      signal(SIGINT, sigHandler );
   }
}

int main ()
{
   signal(SIGINT, sigHandler );

   for (checkForEndlessLoop=0; SOME_SLOPPY_CONDITION; )
   {
      //Some processing here
      if (++checkForEndlessLoop == 0 )
          overflow=true;
   }

   checkForEndlessLoop=0;

   while (SOME_SLOPPY_CONDITION)
   {
      //Some processing here
      if (++checkForEndlessLoop == 0 )
          overflow=true;
   }

}

Or even simpler is, just ignore the SIGINT using SIG_IGN and break out of the faulty loop as soon as the faulty condition is detected, print out an error message and exit!

Pavan Manjunath
  • 27,404
  • 12
  • 99
  • 125