bug-gawk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Ignored SIGPIPE with line bufferization (wrapped by 'stdbuf -oL')


From: Nikita Zlobin
Subject: Re: Ignored SIGPIPE with line bufferization (wrapped by 'stdbuf -oL')
Date: Fri, 29 Jul 2022 15:14:35 +0500

In Thu, 28 Jul 2022 18:04:06 -0400
"Andrew J. Schorr" <aschorr@telemetry-investments.com> wrote:

> Hi,
> 
> On Fri, Jul 29, 2022 at 12:56:35AM +0500, Nikita Zlobin wrote:
> > There's case, when it ignores SIGPIPE, but that happens only with
> > line bufferization (using stdbuf). Disabled bufferization or manual
> > flush (no stdbuf used) don't cause such problem.
> > 
> > First reported for gentoo:
> > https://bugs.gentoo.org/830705
> > 
> > Besides releases this bug reproduces with git version
> > (commit 74fcab9e4307e0d6a85c6e269eed3da276df08a4).
> > 
> > Minimal working example:
> > yes | stdbuf -oL gawk '{print}' | head -n1 # Prints but hangs
> > yes | stdbuf -o0 gawk '{print}' | head -n1 # OK
> > yes | gawk '{print; fflush()}'  | head -n1 # OK
> > 
> > head -n1 process usually disappears.
> > stdbuf is from coreutils-8.32-r1.
> 
> Thanks for the report. This is interesting. Based on some preliminary
> investigation, it seems to me that builtin.c:do_print calls efwrite
> to print the message, and builtin.c:efwrite calls fwrite to send the
> caracters to stdout, and the problem is that fwrite is not reporting
> any error back to gawk. So the question is what is stdbuf doing that
> causes fwrite to return success despite the fact that it's writing to
> a broken pipe. This might be a glibc bug. Or I haven't had enough
> coffee today.

write writes to fd, while fwrite - to FILE stream, where streams are
on top of descriptors. I guess, this difference could be reason.

> 
> With this patch, you can see what is happening:
> 
> diff --git a/builtin.c b/builtin.c
> index 3079540..dae5641 100644
> --- a/builtin.c
> +++ b/builtin.c
> @@ -175,6 +175,8 @@ efwrite(const void *ptr,
>               wrerror(fp, from, rp);
>               return;
>       }
> +     else
> +             fprintf(stderr, "debug: fwrite successfully wrote
> %zu bytes starting with ASCII %d\n", count, (int)*(char *)ptr); if
> (flush && ((fp == stdout && output_is_tty)
>             || (rp != NULL && (rp->flag & RED_NOBUF) != 0)))
> 
> I'm seeing:
> 
> bash-4.2$ (yes | stdbuf -oL ./gawk '{print}' | head -n1) |& head -n20
> debug: fwrite successfully wrote 1 bytes starting with ASCII 121
> debug: fwrite successfully wrote 1 bytes starting with ASCII 10
> debug: fwrite successfully wrote 1 bytes starting with ASCII 121
> debug: fwrite successfully wrote 1 bytes starting with ASCII 10
> debug: fwrite successfully wrote 1 bytes starting with ASCII 121
> debug: fwrite successfully wrote 1 bytes starting with ASCII 10
> debug: fwrite successfully wrote 1 bytes starting with ASCII 121
> debug: fwrite successfully wrote 1 bytes starting with ASCII 10
> debug: fwrite successfully wrote 1 bytes starting with ASCII 121
> debug: fwrite successfully wrote 1 bytes starting with ASCII 10
> debug: fwrite successfully wrote 1 bytes starting with ASCII 121
> debug: fwrite successfully wrote 1 bytes starting with ASCII 10
> debug: fwrite successfully wrote 1 bytes starting with ASCII 121
> debug: fwrite successfully wrote 1 bytes starting with ASCII 10
> debug: fwrite successfully wrote 1 bytes starting with ASCII 121
> debug: fwrite successfully wrote 1 bytes starting with ASCII 10
> debug: fwrite successfully wrote 1 bytes starting with ASCII 121
> debug: fwrite successfully wrote 1 bytes starting with ASCII 10
> debug: fwrite successfully wrote 1 bytes starting with ASCII 121
> debug: fwrite successfully wrote 1 bytes starting with ASCII 10
> 
> If you run with strace, you see that write starts to return -1 with
> EPIPE, but fwrite continues to indicate success:
> 
> bash-4.2$ (yes | stdbuf -oL strace ./gawk '{print}' | head -n1) |&
> head -n200 | tail --- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER,
> si_pid=9053, si_uid=300} --- write(2, "debug: fwrite successfully
> wrote"..., 64debug: fwrite successfully wrote 1 bytes starting with
> ASCII 10 ) = 64 write(2, "debug: fwrite successfully wrote"...,
> 65debug: fwrite successfully wrote 1 bytes starting with ASCII 121 )
> = 65 write(1, "y\n", 2)                      = -1 EPIPE (Broken pipe)
> --- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=9053,
> si_uid=300} --- write(2, "debug: fwrite successfully wrote"...,
> 64debug: fwrite successfully wrote 1 bytes starting with ASCII 10 ) =
> 64 write(2, "debug: fwrite successfully wrote"..., 65debug: fwrite
> successfully wrote 1 bytes starting with ASCII 121
> 
> This is on an old CentOS 7.9 system with glibc 2.17. I haven't tried
> on a newer O/S yet.
> 
> Regards,
> Andy




reply via email to

[Prev in Thread] Current Thread [Next in Thread]