On 2018-10-06 22:12, Paul Eggert wrote:
[snip}
My guess is that you've got an old version of grep on Cygwin, and need
to upgrade to the current version. If you still have problems with the
latest version, please investigate via GDB and/or other means exactly
why grep is failing for you ...
Hi Paul,
I have found what causes grep to fail. (after building v3.1 of grep)
But in order not to mislead others reading this thread, I must correct
what I
wrote in my initial post. There I wrote: "as far as I can tell, the code
that
is executed on Cygwin is not the same as the one that is executed on
Linux".
Wrong. My "strace-ing" misled me.
Returning to grep's failure on Gygwin:
grep terminates with an error on Cygwin because lseek() on Cygwin fails
to
ascertain that it is applied to a FIFO.
As result Cygwin's executive returns EINVAL in errno, in stead of
ESPIPE, as
required (my interpretation after reading "man 2 lseek").
ESPIPE is expected in reset() (src/grep.c), after lseek() has been
applied to
stdin (which points to a FIFO here).
Until v2.26 of grep, a call to S_ISREG(st->st_mode) circumvented the
call to
lseek() (and the call to suppressible_error()) and made reset() return
true.
Version v2.27 of grep removed the call to S_ISREG(st->st_mode). As
result of
that lseek() is invoked.
lseek() fails, but an exception is made for errno == ESPIPE. For this
reason
grep does not fail on Linux (reset() returns true).
However on Cygwin, suppressible_error() is called and reset() returns
false,
which makes grep fail on Cygwin.
You can see for yourself in the attached logfiles (GDB sessions).
-----
To what did I apply GDB?
- downloaded the tarball (grep-3.1.tar.xz) from
http://ftp.gnu.org/gnu/grep/
- build grep using "make CFLAG='-O -g3'", both on Linux and Cygwin
Regards,
Henri
64-@@ gdb /drv/e/grep/b3.1/src/grep
GNU gdb (GDB) (Cygwin 7.12.1-2) 7.12.1
...
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /drv/e/grep/b3.1/src/grep...done.
(gdb) set args .
(gdb) br main
Breakpoint 1 at 0x10040419a: file ../../grep-3.1/src/grep.c, line 2415.
(gdb) br reset
Breakpoint 2 at 0x1004032bc: file ../../grep-3.1/src/grep.c, line 847.
(gdb) br grep.c:856 <==== break-point on "if (seek_failed)" in grep.c/reset()
Breakpoint 3 at 0x100403850: file ../../grep-3.1/src/grep.c, line 856.
(gdb) run
Starting program: /drv/e/grep/b3.1/src/grep .
[New Thread 4684.0xe28]
[New Thread 4684.0x834]
Thread 1 hit Breakpoint 1, main (argc=2, argv=0xffffcc40) at
../../grep-3.1/src/grep.c:2415
2415 {
(gdb) p dup2(open("fifo", 0), 0) # make stdin refer to the fifo ...
<GDB does not return because the open() call blocks>
Using another terminal, execute: echo aaa > fifo (open() for write resumes
the open() call above)
$1 = 0
(gdb) cont
Continuing.
Thread 1 hit Breakpoint 2, grep (ineof=<synthetic pointer>, st=0xffffc940,
fd=0) at ../../grep-3.1/src/grep.c:1447
1447 if (! reset (fd, st))
(gdb) cont
Continuing.
Thread 1 hit Breakpoint 3, reset (st=0xffffc940, fd=0) at
../../grep-3.1/src/grep.c:856
856 if (seek_failed)
(gdb) p seek_failed
$2 = true
(gdb) p bufoffset
$3 = -1
(gdb) p errno
$4 = 22 # EINVAL, because NT returns ERROR_INVALID_PARAMETER (= 87)
(gdb) p errno=29 # replace w/ ESPIPE (= illegal seek)
$5 = 29
(gdb) cont
Continuing.
aaa # output of grep as expected/desired
[Inferior 1 (process 4684) exited normally]
(gdb) quit
64-@@
Q: why is the fifo not recognized as a pipe by Cygwin? (why does Linux
recognize it a fifo/pipe?)
=====
@@ gdb /home/proj/grep/b3.1/src/grep
GNU gdb (GDB) Fedora 7.11.1-86.fc24
...
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /home/proj/grep/b3.1/src/grep...done.
(gdb) set args . < fifo
(gdb) br reset
Breakpoint 1 at 0x4050c2: file ../../grep-3.1/src/grep.c, line 847.
(gdb) br grep.c:856 <==== break-point on "if (seek_failed)" in grep.c/reset()
Breakpoint 2 at 0x4055d6: file ../../grep-3.1/src/grep.c, line 856.
(gdb) run
Starting program: /home/proj/grep/b3.1/src/grep . < fifo
<GDB does not return because the open() call blocks>
Using another terminal, execute: echo aaa > fifo (open() for write resumes
the open() call above)
Missing separate debuginfos, use: dnf debuginfo-install
glibc-2.23.1-12.fc24.x86_64
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Breakpoint 1, grep (ineof=<synthetic pointer>, st=0x7fffffffdaa0, fd=0) at
../../grep-3.1/src/grep.c:1447
1447 if (! reset (fd, st))
Missing separate debuginfos, use: dnf debuginfo-install pcre-8.41-1.fc24.x86_64
(gdb) cont
Continuing.
Breakpoint 2, reset (st=0x7fffffffdaa0, fd=0) at ../../grep-3.1/src/grep.c:856
856 if (seek_failed)
(gdb) p seek_failed
$1 = true
(gdb) p bufoffset
$2 = -1
(gdb) p errno
$3 = 29 # ESPIPE (= illegal seek)
(gdb) cont
Continuing.
aaa # output of grep as expected/desired
[Inferior 1 (process 10652) exited normally]
(gdb) quit
@@
=====