Your message dated Mon, 31 Jul 2017 16:43:19 +0200 with message-id <[email protected]> and subject line Re: Bug#858529: libc6: fgets repeats content after fork on stretch only has caused the Debian Bug report #858529, regarding libc6: fgets repeats content after fork on stretch only to be marked as done.
This means that you claim that the problem has been dealt with. If this is not the case it is now your responsibility to reopen the Bug report if necessary, and/or fix the problem forthwith. (NB: If you are a system administrator and have no idea what this message is talking about, this may indicate a serious mail system misconfiguration somewhere. Please contact [email protected] immediately.) -- 858529: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=858529 Debian Bug Tracking System Contact [email protected] with problems
--- Begin Message ---Package: libc6 Version: 2.24-9 Severity: normal Dear Maintainers, I'm testing a programming exercise for students, and found failed tests that I believe are due to libc6. I retried the minimal test case on every machine I have access to, and found that only my two Debian Stretch machines failed, then took a clean vagrant Jessie box, confirmed correct behavior, updated to Stretch, and reproduced the error. I expect the following code to print its input, once. Instead, it prints lines two through four twice. (abcdbcd). #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> int main() { char buf[255]; int ln=1; int status; FILE *f; f = fopen("/tmp/fourlines", "w"); fprintf(f, "a\nb\nc\nd\n"); fclose(f); f= fopen("/tmp/fourlines", "r"); printf("%d: %s", ln++, fgets(buf, 255, f)); if(fork() == 0) { exit(1); } wait(&status); if(fgets(buf, 255, f)) printf("%d: %s", ln++, buf); if(fgets(buf, 255, f)) printf("%d: %s", ln++, buf); if(fgets(buf, 255, f)) printf("%d: %s", ln++, buf); if(fgets(buf, 255, f)) printf("%d: %s", ln++, buf); if(fgets(buf, 255, f)) printf("%d: %s", ln++, buf); if(fgets(buf, 255, f)) printf("%d: %s", ln++, buf); exit(0); } Output on my two machines and vm with 2.24-9: 1: a 2: b 3: c 4: d 5: b 6: c 7: d The behavior is consistent under the debugger; I don't see anything obvious in the FILE structure, and notice that a read occurs between the d and b (the end of input and when what should be old data is back in). I plan to look into slightly older libc6 versions to find the regression, but that will take me some time. This is sent from the virtual machine, to keep it as clean as possible. -- System Information: Debian Release: 9.0 APT prefers testing APT policy: (500, 'testing') Architecture: amd64 (x86_64) Kernel: Linux 3.16.0-4-amd64 (SMP w/1 CPU core) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) Versions of packages libc6 depends on: ii libgcc1 1:6.3.0-6 libc6 recommends no packages. Versions of packages libc6 suggests: ii debconf [debconf-2.0] 1.5.60 pn glibc-doc <none> ii libc-l10n 2.24-9 ii locales 2.24-9 -- debconf information: glibc/restart-failed: glibc/kernel-too-old: glibc/upgrade: true glibc/restart-services: glibc/disable-screensaver: glibc/kernel-not-supported: * libraries/restart-without-asking: true
--- End Message ---
--- Begin Message ---On 2017-03-23 15:38, Florian Weimer wrote: > tags 858529 upstream > forwarded 858529 https://sourceware.org/bugzilla/show_bug.cgi?id=20598 > thanks > > * Neil Spring: > > > if(fork() == 0) { exit(1); } > > exit flushes the stdio buffers in the child. Upstream concluded that > this leads to undefined behavior: > > | Yes, this is about the exit actually. But reading "2.5.1 > | Interaction of File Descriptors and Standard I/O Streams", I think > | this is really undefined, because the required action is not > | performed before the call to fork, and the correct fix is to use > | _exit in the forked child. For more details here is the link corresponding to the POSIX reference, chapter 2.5.1: http://pubs.opengroup.org/onlinepubs/007904875/functions/xsh_chap02_05.html The behaviour is therefore undefined, and thus is allowed to change between glibc 2.19 and 2.24. As written the above link, two solutions are possible to fix the code: if(fork() == 0) { fclose(fd); exit(1); } or if(fork() == 0) { _exit(1); } I am therefore closing the bug. -- Aurelien Jarno GPG: 4096R/1DDD8C9B [email protected] http://www.aurel32.net
--- End Message ---

