Mail Archives: cygwin/2025/10/27/15:11:23
| DMARC-Filter: | OpenDMARC Filter v1.4.2 delorie.com 59RJBMEt474741
|
| Authentication-Results: | delorie.com; dmarc=pass (p=none dis=none) header.from=cygwin.com
|
| Authentication-Results: | delorie.com; spf=pass smtp.mailfrom=cygwin.com
|
| DKIM-Filter: | OpenDKIM Filter v2.11.0 delorie.com 59RJBMEt474741
|
| Authentication-Results: | delorie.com;
|
| dkim=fail reason="signature verification failed" (1024-bit key, unprotected) header.d=cygwin.com header.i=@cygwin.com header.a=rsa-sha256 header.s=default header.b=b1VZIjGT
|
| X-Recipient: | archive-cygwin AT delorie DOT com
|
| DKIM-Filter: | OpenDKIM Filter v2.11.0 sourceware.org 232453858406
|
| DKIM-Signature: | v=1; a=rsa-sha256; c=relaxed/relaxed; d=cygwin.com;
|
| s=default; t=1761592280;
|
| bh=w7Y02qaQSRbJ6dJ+zXpkElEiM9Crl3TxwwgMbRQ7Otc=;
|
| h=Resent-From:Resent-Date:Resent-To:Date:To:Subject:References:
|
| In-Reply-To:List-Id:List-Unsubscribe:List-Archive:List-Post:
|
| List-Help:List-Subscribe:From:Reply-To:From;
|
| b=b1VZIjGTGQl9bY+SIPuQxYnb0OY++lE3hA1BQRDRurhtZExfTthFJIeNc+91lnEsx
|
| s5oB+N+04K3LDLPbUuJlKzPTbvTV5XLEYCWBMTpacWRQd/3U0Pz3lutSJc7DA8W9Xn
|
| ktF9LKrbpPREWBwH+0YBcg6G6qAHfe9Aqgj0CAm8=
|
| X-Original-To: | cygwin AT cygwin DOT com
|
| Delivered-To: | cygwin AT cygwin DOT com
|
| DKIM-Filter: | OpenDKIM Filter v2.11.0 sourceware.org 7B46C3858D20
|
| Resent-From: | root <root AT server2 DOT sourceware DOT org>
|
| Resent-Date: | Mon, 27 Oct 2025 19:10:03 +0000
|
| Resent-Message-ID: | <aP/Di4qXErci3l2Z AT server2 DOT sourceware DOT org>
|
| Resent-To: | cygwin AT cygwin DOT com
|
| X-Original-To: | spam AT localhost
|
| Delivered-To: | spam AT localhost
|
| DMARC-Filter: | OpenDMARC Filter v1.4.2 sourceware.org F2AE63858428
|
| ARC-Filter: | OpenARC Filter v1.0.0 sourceware.org F2AE63858428
|
| ARC-Seal: | i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1760569147; cv=none;
|
| b=qtWAYNS6XdGY1+NnpuId2YVUri1qZoCK5IQexNr8UryRJuA89vrwWeSCkqGUVTAHTU71r9hkcUGa0HWd3sl5iq2ctjhI3VT9VrVWnG0khTPqFEVZ8nm++nhnWL6DDqhQR5N+37cPLxKhteWxQCsIL9GsvSGhu6w6ctIuYbgtREs=
|
| ARC-Message-Signature: | i=1; a=rsa-sha256; d=sourceware.org; s=key;
|
| t=1760569147; c=relaxed/simple;
|
| bh=tvr4A4DjrHJOrUW12BQAeQlhSIkmpmHRJp/8kwI4sC0=;
|
| h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version;
|
| b=sqSM9oHPqVvoElhBqfPBknV+tZSYEs+OxBhkMuQACdohSmYXUHzSwgIFpHHw5+c+DaP0DqQtom6QfkQyJ8VttWLh8qh1f7qnDvFqFh94v6Xr5yaWeP9k1qXUrLP6DEJJgZoXwxeNHo+fmlA+y2SzAYDkZfw0twH25PUe0qW/xS0=
|
| ARC-Authentication-Results: | i=1; server2.sourceware.org
|
| DKIM-Filter: | OpenDKIM Filter v2.11.0 sourceware.org F2AE63858428
|
| Date: | Thu, 16 Oct 2025 09:59:02 +1100
|
| To: | cygwin AT cygwin DOT com
|
| Subject: | Re: bash hangs when executing a script with a here document larger
|
| than 64 KiB
|
| Message-ID: | <aPAnNroNmsaDtGvM@dimstar.local.net>
|
| Mail-Followup-To: | cygwin AT cygwin DOT com
|
| References: | <6844953 DOT 4vTCxPXJkl AT nimes>
|
| <6f388d6d-e0b1-46a6-a4fb-9f1e008345a7 AT SystematicSW DOT ab DOT ca>
|
| <aOH61MY8W2lZMWWb AT dimstar DOT local DOT net>
|
| MIME-Version: | 1.0
|
| In-Reply-To: | <aOH61MY8W2lZMWWb@dimstar.local.net>
|
| X-Atmail-Id: | duncan_roe AT optusnet DOT com DOT au
|
| X-atmailcloud-spam-action: | no action
|
| X-Cm-Analysis: | v=2.4 cv=DqVQ+n/+ c=1 sm=1 tr=0 ts=68f02738
|
| a=6uXT7DF6Lsg9xELlzDb1tA==:117 a=6uXT7DF6Lsg9xELlzDb1tA==:17
|
| a=PgLrZpBLtpqfETd_:21 a=kj9zAlcOel0A:10 a=x6icFKpwvdMA:10 a=mDV3o1hIAAAA:8
|
| a=_WHcllxdV6XNJ3E_sTMA:9 a=CjuIK1q_8ugA:10 a=RKkw-53RgDYA:10
|
| X-Cm-Envelope: | MS4xfOc+KibLI57rUsmQ0hN7p1UIJ/EsoA4jxXjK+Kg8h3nEFkmJ3ocgjxFytiifmAc3STLtd1H2yXaCnaylEMcGSddz88JlhHsV/Q/bb2jhovUYZrJLYxEl
|
| p8Ehccr2usgKph2RfdbEODfbBrDrHhXR+aNYgCBsFgQdwJTPjK+vfnqeFDiu+pGxeunkv1ZqZjYuJg==
|
| X-atmailcloud-route: | unknown
|
| X-BeenThere: | cygwin AT cygwin DOT com
|
| X-Mailman-Version: | 2.1.30
|
| List-Id: | General Cygwin discussions and problem reports <cygwin.cygwin.com>
|
| List-Unsubscribe: | <https://cygwin.com/mailman/options/cygwin>,
|
| <mailto:cygwin-request AT cygwin DOT com?subject=unsubscribe>
|
| List-Archive: | <https://cygwin.com/pipermail/cygwin/>
|
| List-Post: | <mailto:cygwin AT cygwin DOT com>
|
| List-Help: | <mailto:cygwin-request AT cygwin DOT com?subject=help>
|
| List-Subscribe: | <https://cygwin.com/mailman/listinfo/cygwin>,
|
| <mailto:cygwin-request AT cygwin DOT com?subject=subscribe>
|
| From: | Duncan Roe via Cygwin <cygwin AT cygwin DOT com>
|
| Reply-To: | Duncan Roe <duncan_roe AT optusnet DOT com DOT au>
|
| Errors-To: | cygwin-bounces~archive-cygwin=delorie DOT com AT cygwin DOT com
|
| Sender: | "Cygwin" <cygwin-bounces~archive-cygwin=delorie DOT com AT cygwin DOT com>
|
On Sun, Oct 05, 2025 at 08:03:34AM +0200, cygwin wrote:
> On 10/5/2025 6:57 AM, Duncan Roe via Cygwin wrote:
> > On Thu, Sep 18, 2025 at 02:17:12PM -0600, cygwin wrote:
> > > On 2025-09-18 13:09, Bruno Haible via Cygwin wrote:
> > > > Please, can you handle this bug report, specific to Cygwin?
> > > > The GNU bash maintainer cannot reproduce it, as he doesn't use Cygwin.
> > > >
> > > > https://lists.gnu.org/archive/html/bug-bash/2025-09/msg00186.html
> > > Confirm it hangs in bash but not with dash/ash:
> > >
> > > $ dash ./here-toobig.sh
> > > here-toobig.sh: error: cannot find input file: 'Makefile.in'
> > > $ grep -nC3 echo\ \'BEGIN here-toobig.sh
> > > 861- ac_cs_awk_cr=$ac_cr
> > > 862-fi
> > > 863-
> > > 864:echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
> > > 865-cat >>"$ac_tmp/subs1.awk" <<\_ACAWK &&
> > > 866-S["gltests_libgnu_LIBOBJDEPS"]=""
> > > 867-S["gltests_libgnu_LTLIBOBJS"]=""
> > > $ awk '866 <= FNR && FNR <= 2710' here-toobig.sh | wc -lwmcL
> > > 1845 2041 65563 65563 177
> > >
> > > and Cygwin works with 64KB "pages" and temp buffer sizes.
> > >
> > This only affects here documents over 64KB by 128 bytes or less. The
> > underlying cause is a bug in Windows or Cygwin which damages the build
> > process.
> >
> > Bash tries to send here document data to the target via a pipe. It has to
> > write the entire document to the pipe before any of it get read. Bash
> > checks that the system it's running on can accept that much data in a
> > pipe, otherwise bash uses a temporary file.
> >
> > In redir.c, bash first checks that the here document is smaller than the
> > pipe capacity calculated at build time. This value is wrong because of the
> > bug.
> >
> > Bash then re-checks the pipe capacity using fcntl(F_GETPIPE_SZ) if that
> > fcntl is available. Under cygwin it is not.
> >
> > The build process runs psize.aux (built from builtins/psize.c) to get pipe
> > capacity. Below is a condensed free-standing version of psize.c (no bash
> > includes nor GNU header):-
> >
> > | /* psize.c - Find pipe size. */
> > |
> > | /* Copyright (C) 1987, 1991 Free Software Foundation, Inc.
> > | Copyright (C) 2025 Duncan Roe
> > | */
> > |
> > | /* Write output in 128-byte chunks until we get a sigpipe or write gets an
> > | EPIPE. Then report how many bytes we wrote. We assume that this is the
> > | pipe size. */
> > |
> > | #include <unistd.h>
> > | #include <stdio.h>
> > | #include <signal.h>
> > | #include <errno.h>
> > | #include <stdlib.h>
> > | #include <string.h>
> > | #include <unistd.h>
> > |
> > | int nw;
> > |
> > | static void
> > | sigpipe (int sig, siginfo_t *siginfo, void *ucontext)
> > | {
> > | fprintf (stderr, "%d\n", nw);
> > | exit (0);
> > | }
> > |
> > | int
> > | main (int argc, char **argv)
> > | {
> > | char buf[128];
> > | register int i;
> > | static struct sigaction act;
> @ | /* NEW SINCE Oct 05 */
> @ | sleep(15); /* NEW SINCE Oct 05 */
> > |
> > | for (i = 0; i < 128; i++)
> > | buf[i] = ' ';
> > |
> > | memset(&act, 0, sizeof act);
> > | act.sa_sigaction = sigpipe;
> > | act.sa_flags = SA_SIGINFO;
> > | sigemptyset(&act.sa_mask);
> > | sigaddset(&act.sa_mask, SIGPIPE);
> > | sigaction(SIGPIPE, &act, NULL);
> > |
> > | nw = 0;
> > | for (;;)
> > | {
> > | int n;
> > | n = write (1, buf, 128);
> > | nw += n;
> > | }
> > | return (0);
> > | }
> >
> > `make` runs this as `psize.aux | sleep 3` which gives plenty of time to
> > fill the pipe before getting SIGPIPE when it outputs how much it has
> > written.
> >
> > To see what goes wrong, first build psize.exe:-
> >
> > | gcc psize.c -g3 -gdwarf-5 -o psize
> >
> > Now run psize with a longer sleep time so you can attach gdb to it and
> > enter a few commands (I used sleep 300 and killed sleep once gdb was
> > ready)(blank lines omitted):-
> >
> > | Script started on 2025-10-04 21:24:09+10:00 [TERM="xterm-direct" TTY="/dev/pty1" COLUMNS="88" LINES="98"]
> > | 21:24:11$ gdb -q -p $(pgrep psize)
> > | Attaching to process 9764
> > | [New Thread 9764.0x11c0]
> > | [New Thread 9764.0x38ac]
> > | [New Thread 9764.0x3740]
> > | Reading symbols from /home/dunc/tests/psize/psize.exe...
> > | (gdb) watch nw
> > | Hardware watchpoint 1: nw
> > | (gdb) b sigpipe
> > | Breakpoint 2 at 0x100401096: file psize.c, line 24.
> > | (gdb) c
> > | Continuing.
> > | [Thread 9764.0x3740 exited with code 0]
> > | [Switching to Thread 9764.0x50c]
> > | Thread 1 "psize" hit Hardware watchpoint 1: nw
> > | Old value = 65536
> > | New value = 65664
> > | main (argc=1, argv=0xa000004e0) at psize.c:47
> > | 47 {
> > | (gdb) n
> > | 49 n = write (1, buf, 128);
> > | (gdb)
> > | Thread 1 "psize" received signal SIGPIPE, Broken pipe.
> > | 0x00007ffeeefcd574 in ntdll!ZwWaitForSingleObject ()
> > | from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
> > | (gdb) signal SIGPIPE
> > | Continuing with signal SIGPIPE.
> > | Thread 1 "psize" hit Breakpoint 2, sigpipe (sig=13, siginfo=0x7ffffbdd0,
> > | ucontext=0x7ffffbf50) at psize.c:24
> > | 24 fprintf (stderr, "%d\n", nw);
> > | (gdb) n
> > | 25 exit (0);
> > | (gdb)
> > | [Thread 9764.0x50c exited with code 0]
> > | [Thread 9764.0x38ac exited with code 0]
> > | [Inferior 1 (process 9764) exited normally]
> > | (gdb) q
> > | 21:27:59$ s
> > | exit
> > | Script done on 2025-10-04 21:28:17+10:00 [COMMAND_EXIT_CODE="0"]
> >
> > SIGPIPE interrupts write() which returns 128 as if it had succeeded!
> >
> > The signal is only delivered to psize after it tries another write().
> >
> > There has to be a bug in there somewhere.
> The bug is in understanding that the design of read(2), write(2), fread(3)
> etc.
> all requirethat upon approaching the limit, they must first succeed within
> their limit before theycan return 0 or raise a signal to indicate actually
> hitting the limit .
>
> Also check if the Cygwin implementation of write() contains a hidden buffer
> thatpretends to write beyond the actual kernel level pipe limit, in which
> case the testprogram needs to somehow bypass that without becoming
> complicated.
TL;DR
After more debugging (a lot more) I don't see anything resembling what you
postulate above. What I do see is cygwin in a wait loop trying to write to the
pipe. This is how cygwin treats a blocking pipe, presumably in the expectation
that the next process in the pipeline will read from the pipe eventually.
This is the psize backtrace:-
| (gdb) bt
| #0 0x00007ffeeefce044 in ntdll!ZwWaitForMultipleObjects ()
| from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
| #1 0x00007ffeec990d00 in WaitForMultipleObjectsEx ()
| from /cygdrive/c/WINDOWS/System32/KERNELBASE.dll
| #2 0x00007ffeec990bfe in WaitForMultipleObjects ()
| from /cygdrive/c/WINDOWS/System32/KERNELBASE.dll
| #3 0x00007ffecbbc6044 in cygwait (object=<optimized out>,
| timeout=timeout AT entry=0x7ffffca70, mask=mask AT entry=1)
| at /usr/src/debug/cygwin-3.6.4-1/winsup/cygwin/cygwait.cc:79
| #4 0x00007ffecbca1787 in cygwait (mask=1, howlong=10, h=<optimized out>)
| at /usr/src/debug/cygwin-3.6.4-1/winsup/cygwin/local_includes/cygwait.h:45
| #5 fhandler_pipe_fifo::raw_write (len=128, ptr=0x7ffffcba0, this=0x8000102f0)
| at /usr/src/debug/cygwin-3.6.4-1/winsup/cygwin/fhandler/pipe.cc:631
| #6 fhandler_pipe_fifo::raw_write (this=0x8000102f0, ptr=<optimized out>, len=128)
| at /usr/src/debug/cygwin-3.6.4-1/winsup/cygwin/fhandler/pipe.cc:445
| #7 0x00007ffecbc4dc6e in write (fd=1, ptr=0x7ffffcba0, len=128)
| at /usr/src/debug/cygwin-3.6.4-1/winsup/cygwin/local_includes/dtable.h:64
| #8 0x00007ffecbd0ae74 in _sigfe () at sigfe.s:35
| #9 0x000000010040118c in main (argc=1, argv=0xa000004e0) at psize.c:49
This is the wait loop:-
| #5 fhandler_pipe_fifo::raw_write (len=128, ptr=0x7ffffcba0, this=0x8000102f0)
| at /usr/src/debug/cygwin-3.6.4-1/winsup/cygwin/fhandler/pipe.cc:631
| 631 if (WAIT_OBJECT_0 == cygwait (select_sem, 10, cw_cancel))
| (gdb) n
| 610 waitret = cygwait (evt, (DWORD) 0);
| (gdb)
| 611 if (signalled && !saw_select_sem
| (gdb)
| 616 if (waitret == WAIT_SIGNALED)
| (gdb)
| 622 if (waitret == WAIT_OBJECT_0)
| (gdb)
| 626 if (waitret == WAIT_TIMEOUT && short_write_once)
| (gdb)
| 631 if (WAIT_OBJECT_0 == cygwait (select_sem, 10, cw_cancel))
When bash hangs, frames 0-8 of the stack trace are near-identical:-
| (gdb) bt
| #0 0x00007ffeeefce044 in ntdll!ZwWaitForMultipleObjects ()
| from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
| #1 0x00007ffeec990d00 in WaitForMultipleObjectsEx ()
| from /cygdrive/c/WINDOWS/System32/KERNELBASE.dll
| #2 0x00007ffeec990bfe in WaitForMultipleObjects ()
| from /cygdrive/c/WINDOWS/System32/KERNELBASE.dll
| #3 0x00007ffecbbc6044 in cygwait (object=<optimized out>,
| timeout=timeout AT entry=0x7ffffbfd0, mask=mask AT entry=1)
| at /usr/src/debug/cygwin-3.6.4-1/winsup/cygwin/cygwait.cc:79
| #4 0x00007ffecbca1787 in cygwait (mask=1, howlong=10, h=<optimized out>)
| at /usr/src/debug/cygwin-3.6.4-1/winsup/cygwin/local_includes/cygwait.h:45
| #5 fhandler_pipe_fifo::raw_write (len=65573, ptr=0xa000a28b0, this=0x80000b610)
| at /usr/src/debug/cygwin-3.6.4-1/winsup/cygwin/fhandler/pipe.cc:631
| #6 fhandler_pipe_fifo::raw_write (this=0x80000b610, ptr=<optimized out>, len=65573)
| at /usr/src/debug/cygwin-3.6.4-1/winsup/cygwin/fhandler/pipe.cc:445
| #7 0x00007ffecbc4dc6e in write (fd=4, ptr=0xa000928b0, len=65573)
| at /usr/src/debug/cygwin-3.6.4-1/winsup/cygwin/local_includes/dtable.h:64
| #8 0x00007ffecbd0ae74 in _sigfe () at sigfe.s:35
| #9 0x000000010047e161 in heredoc_write (fd=4,
| heredoc=0xa000928b0 "abcdefghijklmnopqrstuvwxyz012345"..., herelen=65573)
| at ../redir.c:422
| #10 0x000000010047e299 in here_document_to_fd (redirectee=0xa00035870,
| ri=r_reading_until) at ../redir.c:487
| #11 0x000000010047f0f1 in do_redirection_internal (redirect=0xa0006cb30, flags=3,
| fnp=0x7ffffc228) at ../redir.c:1056
| #12 0x000000010047dd4e in do_redirections (list=0xa0006cb30, flags=3) at ../redir.c:263
| #13 0x00000001004248d7 in execute_builtin_or_function (words=0xa0006d200,
| builtin=0x10049282a <mapfile_builtin>, var=0x0, redirects=0xa0006cb30,
| fds_to_close=0xa0006cb10, flags=0) at ../execute_cmd.c:5458
| #14 0x00000001004231d0 in execute_simple_command (simple_command=0xa0006caf0,
| pipe_in=-1, pipe_out=-1, async=0, fds_to_close=0xa0006cb10)
| at ../execute_cmd.c:4741
| #15 0x000000010041bcb9 in execute_command_internal (command=0xa0006cac0,
| asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0xa0006cb10)
| at ../execute_cmd.c:870
| #16 0x000000010048cb28 in parse_and_execute (
| string=0xa0005c190 "# dot this file from bash runnin"...,
| from_file=0xa0005c0a0 "./toobig_sh", flags=1044) at ../../builtins/evalstring.c:539
| #17 0x000000010048ba88 in _evalfile (filename=0xa0005c0a0 "./toobig_sh", flags=14)
| at ../../builtins/evalfile.c:285
| #18 0x000000010048bcd4 in source_file (filename=0xa0005c0a0 "./toobig_sh", sflags=0)
| at ../../builtins/evalfile.c:380
| #19 0x000000010049a020 in source_builtin (list=0xa0005c020)
| at ../../builtins/../../builtins/source.def:195
| #20 0x0000000100423977 in execute_builtin (builtin=0x100499c30 <source_builtin>,
| words=0xa000330b0, flags=0, subshell=0) at ../execute_cmd.c:4975
| #21 0x0000000100424996 in execute_builtin_or_function (words=0xa000330b0,
| builtin=0x100499c30 <source_builtin>, var=0x0, redirects=0x0,
| fds_to_close=0xa000331b0, flags=0) at ../execute_cmd.c:5489
| #22 0x00000001004231d0 in execute_simple_command (simple_command=0xa00033170,
| pipe_in=-1, pipe_out=-1, async=0, fds_to_close=0xa000331b0)
| at ../execute_cmd.c:4741
| #23 0x000000010041bcb9 in execute_command_internal (command=0xa00035ad0,
| asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0xa000331b0)
| at ../execute_cmd.c:870
| #24 0x000000010041b137 in execute_command (command=0xa00035ad0) at ../execute_cmd.c:417
| #25 0x0000000100404847 in reader_loop () at ../eval.c:171
| #26 0x0000000100401d73 in main (argc=2, argv=0xa00001fc0, env=0xa00000160)
| at ../shell.c:833
I made a simplified tester to avoid having to deal with forked processes while
debugging:-
| # dot this file from bash running under gdb
| readarray <<////
| abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwx
yz0123456789abcdefghijklmno
[63 more of these 1KB lines]
| abcdefghijklmnopqrstuvwxyz0123456789
| ////
Back to psize, determine where Windows puts the value returned by write(). In
fhandler_pipe_fifo::raw_write() at
/usr/src/debug/cygwin-3.6.4-1/winsup/cygwin/fhandler/pipe.cc:691, observe:-
| nbytes_now = io.Information;
where `io` is declared locally:-
| 444 ssize_t
| 445 fhandler_pipe_fifo::raw_write (const void *ptr, size_t len)
| 446 {
...
| 450 IO_STATUS_BLOCK io;
Want address so can access from anywhere:-
| (gdb) p &io.Information
| $2 = (ULONG_PTR *) 0x7ffffca68
| (gdb) p sizeof(io.Information)
| $8 = 8
Information is an 8-byte variable but this is a L/E system so integers will
appear in the 1st 4 bytes.
Be sure to build the updated psize.c in this email. The 15-second sleep is to
give you time to set breakpoints.
To debug psize, in another terminal do:
| ./psize|sleep 100000
Then run gdb as:
| gdb -p $(pgrep psize)
Set a breakpoint which zeroises io.Information so we know if its contents
change:-
| (gdb) b /usr/src/debug/cygwin-3.6.4-1/winsup/cygwin/fhandler/pipe.cc:457
| Breakpoint 1 at 0x7ffecbca1491: file /usr/src/debug/cygwin-3.6.4-1/winsup/cygwin/fhandler/pipe.cc, line 457.
| (gdb) commands
| Type commands for breakpoint(s) 1, one per line.
| End with a line saying just "end".
| >p io.Information = 0
| >end
| (gdb) b 51 if nw == 65536
| Breakpoint 2 at 0x10040117c: file psize.c, line 51.
| (gdb) commands
| Type commands for breakpoint(s) 2, one per line.
| End with a line saying just "end".
| >silent
| >ena 1
| >c
| >end
| (gdb) disa 1
Breakpoint 1 only fires when we try to write bytes that won't fit.
The breakpoint fires:
| Thread 1 "psize" hit Breakpoint 1, fhandler_pipe_fifo::raw_write (len=128,
| ptr=0x7ffffcba0, this=0x800009a80)
| at /usr/src/debug/cygwin-3.6.4-1/winsup/cygwin/fhandler/pipe.cc:457
| 457 ssize_t avail = pipe_buf_size;
| (gdb) u 602
| fhandler_pipe_fifo::raw_write (len=128, ptr=0x7ffffcba0, this=0x800009a80)
| at /usr/src/debug/cygwin-3.6.4-1/winsup/cygwin/fhandler/pipe.cc:602
| 602 status = NtWriteFile (get_handle (), evt, NULL, NULL, &io,
| (gdb) n
| 606 if (status == STATUS_PENDING)
| (gdb)
| 610 waitret = cygwait (evt, (DWORD) 0);
| (gdb) p *(int *) 0x7ffffca68
| $2 = 0
| (gdb) watch *(int *) 0x7ffffca68
| Hardware watchpoint 3: *(int *) 0x7ffffca68
| # In a 3rd terminal, kill sleep.
| (gdb) p *(int *) 0x7ffffca68
| $4 = 128
io.Information has changed from 0 to 128 without the watchpoint triggering.
(Not shown) I did set breakpoints in all the other threads to report if any of
them woke up. None did.
Another process (perhaps an svchost?) modified the return from write(). Nothing
cygwin or bash can do about that. Hence my suggested fix.
Cheers ... Duncan.
--
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
- Raw text -