lkml.org 
[lkml]   [2011]   [Feb]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: Bash not reacting to Ctrl-C
    On 01/28, Ingo Molnar wrote:
    >
    > * Oleg Nesterov <oleg@redhat.com> wrote:
    >
    > > On 01/28, Ingo Molnar wrote:
    > > >
    > > > The bug is that occasionally Ctrl-C does not get processed, and that the Ctrl-C is
    > > > 'lost'. It can be reproduced here by running ./test-signal several times, and
    > > > Ctrl-C-ing it:
    > > >
    > > > $ ./test-signal
    > > > ^C
    > > > $ ./test-signal
    > > > ^C^C
    > > > $ ./test-signal
    > > > ^C
    > > >
    > > > See that '^C^C' line? That is where i had to do Ctrl-C twice.
    > >
    > > Reproduced.
    > >
    > > At first glance, /bin/sh should be blamed... Hmm, probably yes,
    > > I even reproduced this under strace, and this is what I see
    > >
    > > wait4(-1, 0x7fff388431c4, 0, NULL) = ? ERESTARTSYS (To be restarted)
    > > --- SIGINT (Interrupt) @ 0 (0) ---
    > > rt_sigreturn(0) = -1 EINTR (Interrupted system call)
    > > wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 9706
    > >
    > > So, ^C is not lost, but ./test-signal doesn't want to exit.
    >
    > Might be some Bash assumption or race that works under other OSs but somehow Linux
    > does differently. IIRC Bash is being developed on MacOS-X.
    >
    > But it's happening all the time (with yum for example - but also with makejobs, as
    > Thomas has reported it) - this is simply the first time i managed to reproduce it
    > with something really simple.

    OK, I seem to understand what happens. Of course I am not sure, I never
    looked into these sources before...

    Suppose that jctl ^C races with the normal child exit. In this case
    waitchld() sets child->status = status (zero in this case) and calls
    set_job_status_and_cleanup().

    set_job_status_and_cleanup() notice wait_sigint_received and send
    SIGINT to itself (termsig_handler (SIGINT)), but somehow it assumes
    that the last foreground job should be terminated by SIGINT too:

    else if (wait_sigint_received && (WTERMSIG (child->status) == SIGINT) &&

    Then the next wait_for() clears wait_sigint_received and bash
    looses ^C

    Oleg.



    \
     
     \ /
      Last update: 2011-02-05 21:45    [W:0.266 / U:60.924 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site