bug-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug #41341] Race condition in job.c set_child_handler_action_flags - al


From: anonymous
Subject: [bug #41341] Race condition in job.c set_child_handler_action_flags - alarm is set before SIGALRM handler
Date: Sat, 25 Jan 2014 00:38:17 +0000
User-agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.76 Safari/537.36

URL:
  <http://savannah.gnu.org/bugs/?41341>

                 Summary: Race condition in job.c
set_child_handler_action_flags - alarm is set before SIGALRM handler
                 Project: make
            Submitted by: None
            Submitted on: Sat 25 Jan 2014 12:38:16 AM UTC
                Severity: 3 - Normal
              Item Group: Bug
                  Status: None
                 Privacy: Public
             Assigned to: None
             Open/Closed: Open
         Discussion Lock: Any
       Component Version: 4.0
        Operating System: None
           Fixed Release: None
           Triage Status: None

    _______________________________________________________

Details:

Hi, there is possible race condition in job.c in function
set_child_handler_action_flags when it is called to set alarm. There is short
period of time, when alarm is set, but handler is not set; sometimes this may
kill make process.

The code fragment:

http://git.savannah.gnu.org/cgit/make.git/tree/job.c#n1093

set_child_handler_action_flags (int set_handler, int set_alarm)
{
....
#if defined SIGALRM
  if (set_alarm)
    {
      /* If we're about to enter the read(), set an alarm to wake up in a
         second so we can check if the load has dropped and we can start more
         work.  On the way out, turn off the alarm and set SIG_DFL.  */
      alarm (set_handler ? 1 : 0);
      sa.sa_handler = set_handler ? job_noop : SIG_DFL;
      sa.sa_flags = 0;
      sigaction (SIGALRM, &sa, NULL);
    }
#endif
}
#endif

If we are setting alarm, the order of calls is:

 alarm(1);
 sa.sa_handler=job_noop;
 sigaction(SIGALRM, &sa, NULL);

And when we are unsetting the alarm, the order is

 alarm(0);
 sa.sa_handler=SIG_DFL; // DFL is kill
 sigaction(SIGALRM, &sa, NULL);

So, for the setting of alarm, when used on very slow machine or on very loaded
machine there is probability that make process will do alarm(1) and then will
be descheduled from CPU for time of more than 1 real time second. SIGALRM will
be generated and delivered before sigaction call, killing the make process.

I think the better way of setting the alarm is to register handler BEFORE
setting alarm and deregister it AFTER disabling alarm, like

if(set_handler) {
      sa.sa_handler = job_noop;
      sa.sa_flags = 0;
      sigaction (SIGALRM, &sa, NULL);
      alarm (1);
} else {
      alarm (0);
      sa.sa_handler = SIG_DFL;
      sa.sa_flags = 0;
      sigaction (SIGALRM, &sa, NULL);
}

Thanks!




    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?41341>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]