delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2005/08/29/06:44:55

Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com
X-Authenticated: #14308112
Date: Mon, 29 Aug 2005 13:45:43 +0300
From: Pavel Tsekov <ptsekov AT gmx DOT net>
X-X-Sender: ptsekov AT mordor
To: cygwin AT cygwin DOT com
Subject: Latest findings on zsh hang was Re: Re: zsh: command not found => hangs
In-Reply-To: <18425.1125260276@www86.gmx.net>
Message-ID: <Pine.CYG.4.58.0508291305290.616@mordor>
References: <20050828193433 DOT GA25584 AT trixie DOT casa DOT cgf DOT cx> <18425 DOT 1125260276 AT www86 DOT gmx DOT net>
MIME-Version: 1.0
X-Y-GMX-Trusted: 0
X-IsSubscribed: yes

Hello,

> in cancelable_wait(). The signal handler returns to the wrong place (?) and
> ends up in WaitForMultipleObjects() instead after the sigsuspend() call in
> zsh. I'll see what I can find out. If I find out something which makes more
> sense that what I currently know I'll post.

I have new information on this matter. This time I think I found the real
reason for the hang.

The sigsuspend() function does one simple thing - it calls handle_sigsuspend().
handle_sigsuspend() sets the signal mask to the one passed to sigsuspend()
and then calls cancelable_wait() to wait for a signal which is not in the
mask just set. As part of its setup cancelable_wait() ends up calling
_cygtls::setup_fault() (via pthread::is_good_object()). _cygtls::setup_fault()
ends up calling the assembly routine stabilize_sig_stack() (via setjmp).
stabilize_sig_stack() will call a signal handler if there is a signal to
be processed. This check is used to determine if there is signal to process:

2:      cmpl    $0,-1040(%ebx)

The check is quering the `sig' member of the _cygtls structure. This
member is filled by the interrupt_setup() routine.

Now here is what happens...

zsh forks a non-existen process and the fork fails. SIGCHLD is
delivered to the shell. The signal stays pending for a while since it
is blocked (can be seen from the original strace) zsh. In the meantime
sigsuspend() is called which will mask everything except SIGCHLD and
SIGHUP. Now it happens so that the SIGCHLD signal is delivered before
stabilize_sig_stack() is called. Once stabilize_sig_stack() notices the
signal it calls the signal handler. By the time cancelable_wait()
is called there are no more signals to process and thus the hang.

I hope this sounds reasonable. At least it does to me and I've seen it
happening.

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019