On 11/9/2021 9:53 PM, Ken Brown via Cygwin wrote:
Back to the drawing board.
It finally occurred to me to stop looking for a bug in fhandler_pipe::raw_read
and instead see if something is in fact repeatedly writing to the pipe, so that
drain_signal_event_pipe never finishes. Putting a breakpoint at
fhandler_pipe::raw_write, I found that this is in fact the case. While the main
thread is repeatedly reading from the pipe, a second thread is repeatedly
writing to it. Here's the backtrace of that thread:
#0 fhandler_pipe_fifo::raw_write (this=0x18039f370, ptr=0x2c4ca3b, len=1)
at ../../../../temp/winsup/cygwin/fhandler_pipe.cc:430
#1 0x000000018006f39a in fhandler_base::write (this=0x18039f370,
ptr=0x2c4ca3b, len=1) at ../../../../temp/winsup/cygwin/fhandler.cc:907
#2 0x0000000180158fd1 in write (fd=4, ptr=0x2c4ca3b, len=1)
at ../../../../temp/winsup/cygwin/syscalls.cc:1360
#3 0x00000001801b9b5b in _sigfe () at sigfe.s:35
#4 0x00000001006ae471 in retry_write_1 (fildes=4, buf=0x2c4ca3b, nbyte=1,
allow_quit=0) at sysdep.c:2364
#5 0x00000001006ae581 in retry_write (fildes=4, buf=0x2c4ca3b, nbyte=1)
at sysdep.c:2386
#6 0x00000001004b3ba5 in signal_fake_event () at event-unixoid.c:149
#7 0x0000000100691060 in alarm_signal (signo=14) at signal.c:559
#8 0x00000001006ec6e4 in mswindows_raise (nsig=14) at win32.c:694
#9 0x00000001006ec72d in setitimer_helper_proc (unused_uID=96, unused_uMsg=0,
dwUser=14, unused_dw1=0, unused_dw2=0) at win32.c:742
#10 0x00007ffb363c2811 in WINMM!PlaySoundW () from /c/WINDOWS/SYSTEM32/WINMM.dll
#11 0x000000018004771c in _cygtls::call2 (this=0x2c4ce00,
func=0x7ffb363c26c0 <WINMM!PlaySoundW+3440>, arg=0x0, buf=0x2c4cce0)
at ../../../../temp/winsup/cygwin/cygtls.cc:40
#12 0x00000001800476c1 in _cygtls::call (
func=0x7ffb363c26c0 <WINMM!PlaySoundW+3440>, arg=0x0)
at ../../../../temp/winsup/cygwin/cygtls.cc:27
#13 0x00000001800e4f15 in threadfunc_fe (arg=0x0)
at ../../../../temp/winsup/cygwin/init.cc:28
#14 0x00007ffb43da7034 in KERNEL32!BaseThreadInitThunk ()
from /c/WINDOWS/System32/KERNEL32.DLL
#15 0x00007ffb448c2651 in ntdll!RtlUserThreadStart ()
from /c/WINDOWS/SYSTEM32/ntdll.dll
#16 0x0000000000000000 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
This looks to me like an XEmacs bug that happens to be triggered by the new pipe
code, although maybe there's also a Cygwin bug that I'm not seeing. The comment
at the beginning of signal_fake_event might be relevant:
void
signal_fake_event (void)
{
Rawbyte rbyte = 0;
/* We do the write always. Formerly I tried to "optimize" this
by setting a flag indicating whether we're blocking and only
doing the write in that case, but there is a race condition
if the signal occurs after we've checked for the signal
occurrence (which could occur in many places throughout
an iteration of the command loop, e.g. in status_notify()),
but before we set the blocking flag.
This should be OK as long as write() is reentrant, which I'm fairly
sure it is since it's a system call. */
if (signal_event_pipe_initialized)
/* In case a signal comes through while we're dumping */
{
int old_errno = errno;
retry_write (signal_event_pipe[1], &rbyte, 1);
errno = old_errno;
}
}
Ken
--
Problem reports: https://cygwin.com/problems.html
FAQ: https://cygwin.com/faq/
Documentation: https://cygwin.com/docs.html
Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple