Another pipe-related problem?

Ken Brown kbrown@cornell.edu
Wed Nov 10 14:47:31 GMT 2021


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


More information about the Cygwin mailing list