Christian Franke via Cygwin wrote:
Christian Franke via Cygwin wrote:
Found during test of 'stress-ng --pseek ...' from current upstream
stress-ng git HEAD:
Testcase:
$ uname -r
3.5.4-1.x86_64
$ cat pfail.c
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
int fd = open("pwrite.tmp", O_RDWR|O_CREAT|O_BINARY, 0666);
if (fd < 0) {
perror("open"); return 1;
}
char c = 42;
if (pwrite(fd, &c, 1, 0) < 0)
perror("pwrite");
if (fork() == 0) {
if (pread(fd, &c, 1, 0) < 0)
perror("pread");
_exit(0);
}
int status;
wait(&status);
return 0;
}
$ make pfail
cc pfail.c -o pfail
$ ./pfail
pread: Bad file descriptor
$ strace ./pfail
...
617 75356 [main] pfail 10826 dofork: 10827 = fork()
82 11289 [main] pfail 10827 seterrno_from_nt_status:
/usr/src/debug/cygwin-3.5.4-1/winsup/cygwin/fhandler/disk_file.cc:1883
status 0xC0000008 -> windows error 6
80 75436 [main] pfail 10826 wait4: calling proc_subproc, pid -1,
options 0
76 11365 [main] pfail 10827 geterrno_from_win_error: windows
error 6 == errno 9
78 75514 [main] pfail 10826 proc_subproc: args: 5, -7728
64 11429 [main] pfail 10827 pread: -1 = pread(3, 0x7FFFFCC0B, 1,
0), errno 9
...
The problem does not occur if there is no pread()/pwrite() before the
fork(). This suggests that the child process inherits the extra
handle value used to keep the original seek position, but not the
actual handle.
The mentioned extra handle 'prw_handle' is set to null after fork here:
https://cygwin.com/git/?p=newlib-cygwin.git;a=blob;f=winsup/cygwin/fhandler/disk_file.cc;h=f4c21d3#l1698
But a test suggests that fhandler_disk_file::fixup_after_fork() is
never called or debug_printf() does not work if called in this function.
Possible fix:
https://sourceware.org/pipermail/cygwin-patches/2024q3/012793.html
--
Regards,
Christian
--
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