Subject: bug#77800: grep-3.12: write-error-msg test failure on fedora rawhide (f43)

From: Grisha Levit <[email-masked]>
Date: Tue, 15 Apr 2025 19:12:18 -0400

On Tue, Apr 15, 2025 at 6:38 PM <[email-masked]> wrote:
>
> >> This seems to be fixed if the patch here [1] is _not_ applied when
> >> building the RPM
>
> Can you check, perhaps using strace, whether that problematic patch pushes
> the total amount of bytes written to stdout by grep, writing to /dev/full as you
> invoke it, goes from a little below 4096 bytes, in a single write(2) system call,
> to trying to write more than 4096 bytes, which likely forces two write calls,
> the first 4096 bytes, then the remainder.
>

Indeed, the `--help' output is 4096 bytes normally and longer after the patch:

$ ./src/grep --help | wc -c
4096
$ patch ... && make -C src grep
$ ./src/grep --help | wc -c
4122

ltrace shows:

printf("General help using GNU software:"...,
"https://www.gnu.org/gethelp/") = 64
exit(0 <unfinished ...>
__fpending(0xffff9afe1510, 0, 0xffff9afe2280, 1) = 4096
fclose(0xffff9afe1510)                           = -1
dcgettext(0x41d480, 0x41c418, 5, 0x450000)       = 0x41c418
__errno_location()                               = 0xffff9b0da760
error(0, 28, 0x41c318, 0x41c418)                 = 0xffff9b0ebc90

vs

printf("General help using GNU software:"...,
"https://www.gnu.org/gethelp/") = -1
exit(0 <unfinished ...>
__fpending(0xffff813f1510, 0, 0xffff813f2280, 1) = 0
fclose(0xffff813f1510)                           = 0
__errno_location()                               = 0xffff814e9760
dcgettext(0x41d4a0, 0x41c418, 5, 0x450000)       = 0x41c418
__errno_location()                               = 0xffff814e9760
error(0, 0, 0x41c318, 0x41c418)                  = 0xffff814fac90

and gdb (with the patch applied):

(gdb) n
58   const bool prev_fail = (ferror (stream) != 0);
(gdb) n
close_stream (stream=0xfffff7ef1510 <_IO_2_1_stdout_>) at
/usr/include/bits/stdio.h:137
137   return __ferror_unlocked_body (__stream);
(gdb) n
close_stream (stream=0xfffff7ef1510 <_IO_2_1_stdout_>) at close-stream.c:59
59   const bool fclose_fail = (fclose (stream) != 0);
(gdb) n
69   if (prev_fail || (fclose_fail && (some_pending || errno != EBADF)))
(gdb) p prev_fail
$2 = true
(gdb) p fclose_fail
$3 = false
(gdb) p some_pending
$4 = false
(gdb) p errno
$5 = 28
(gdb) n
71       if (! fclose_fail)
(gdb) n
72         errno = 0;