[BusyBox 0001280]: [patch] signals never get unblocked (a.k.a wait becomes uninterruptible)

bugs at busybox.net bugs at busybox.net
Wed Mar 21 19:34:32 UTC 2007

A NOTE has been added to this issue. 
Reported By:                johny
Assigned To:                BusyBox
Project:                    BusyBox
Issue ID:                   1280
Category:                   Standards Compliance
Reproducibility:            always
Severity:                   block
Priority:                   normal
Status:                     assigned
Date Submitted:             03-20-2007 22:42 PDT
Last Modified:              03-21-2007 12:34 PDT
Summary:                    [patch] signals never get unblocked (a.k.a wait
becomes uninterruptible)
The busybox "ash" shell is signal-challenged, in that it starts ignoring
signal after the first delivery. It also double-fires signals under some
circumstances. This patch fixes the first of those issues. I don't have a
fix for the second issue (and not sure if I'll have time to chase that one
down, since it's not actually breaking things in our environment).

Basically what happens is that when a signal gets delivered, the kernel
automatically blocks any further deliveries of that same signal until the
signal handler returns, or the signal mask is explicitly changed. In
the signal handler longjmp's to elsewhere. As such, the signal mask keeps
getting added to as signals come in, and stuff breaks more and more. This
immediately obvious, since the behaviour only appears for busybox
commands. Commonly things are either executed in a subshell (which then
has the
damage confined to that subshell), or external commands (which don't have

To reproduce, simply run "./busybox ash" (assuming it's built with ash
included of course) and run this sequence:

sleep 10 &
(this might return right away due to the last ^C getting re-fired - bug

As you'll notice, the last ^C has no effect at all, due to SIGINT being
blocked after the first ^C was pressed. With the attached patch, it
behaves as expected. The instant return of the second "wait" is still
present however.

I've run the test case on a 1.1.3 system too, and it too has the same bug.

 vda - 03-21-07 12:34  
Thanks for the fix. Second bug seems to happen in EXSIGON - it raises
exception. "wait: 2" is never reached:

static int
waitcmd(int argc, char **argv)
        struct job *job;
        int retval;
        struct job *jp;

write(2, "wait: 1\n", sizeof("wait: 1\n")-1);
write(2, "wait: 2\n", sizeof("wait: 2\n")-1);

# ./busybox ash
# sleep 10 &
# wait
wait: 1
wait: 2
wait: 3
wait: dowait(DOWAIT_BLOCK, 0)

# wait
wait: 1   <------- HERE

#define EXSIGON \
        do { \
                exsig++; \
                xbarrier(); \
                if (pendingsigs) \
                        raise_exception(EXSIG); \
        } while (0)

Maybe I should add this to your fix?
        sigprocmask(SIG_SETMASK, &mask, 0);
+       pendingsigs = 0; 

Issue History 
Date Modified   Username       Field                    Change               
03-20-07 22:42  johny          New Issue                                    
03-20-07 22:42  johny          Status                   new => assigned     
03-20-07 22:42  johny          Assigned To               => BusyBox         
03-20-07 22:42  johny          File Added: sigmask.patch                    
03-21-07 12:34  vda            Note Added: 0002266                          

More information about the busybox-cvs mailing list