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

Reply via email to