Public bug reported: 1) lsb_release -rd Description: Ubuntu 16.04.3 LTS Release: 16.04
2) apt-cache policy libc6 libc6: Installed: 2.23-0ubuntu10 Candidate: 2.23-0ubuntu10 Version table: *** 2.23-0ubuntu10 500 500 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 Packages 500 http://security.ubuntu.com/ubuntu xenial-security/main amd64 Packages 100 /var/lib/dpkg/status 2.23-0ubuntu3 500 3) The following program fails to terminate, although it should when compiled with no optimizations. This can be compiled with both clang and gcc and the same behavior described happens. This doesn't seem to happen with older versions of the library [citation needed]. Contents of 123.txt ``` AA\n BB\n CC ``` Code: ``` #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> void h(FILE* fd) { (void)fd; pid_t p = fork(); if(!p) { exit(1); } else { int s; waitpid( p, &s,0); } } int main() { FILE* fd = fopen("123.txt", "r"); size_t cap = 20; ssize_t br = 0; char* buf = malloc(cap); int linecount = 0; while(1) { br = getline( &buf , &cap, fd); if(br == -1) break; puts(buf); h(fd); } free(buf); fclose(fd); return 0; } ``` Expected: ``` AA BB CC ``` Actual: ``` AA BB CC AA BB CC <doesn't terminate> ``` * I believe it is with how the FILE* object is being buffered and how getline is interacting with the buffer with a combination of fork. * If we change main to a syscall only version, it works as expected with the fork ``` int main() { int fd = open("123.txt", O_RDONLY); size_t cap = 20; ssize_t br = 0; char* buf = malloc(cap); int linecount = 0; while(1) { br = read( fd , buf, cap); if (br == -1) break; buf[br] = 0; puts(buf); if (br < cap) break; h(fd); } free(buf); close(fd); return 0; } ``` * The `fread` version of the program terminates as expected. * If the fork call is not there -- the program executes as normal. * If there is any call to `fseek(fd, 0, SEEK_CUR)` after the getline but before the fork, the issues goes away. Not with `ftell(fd)` though. * If there is the same check after the fork, the file is outputted twice and then the program terminates. * The issues also goes away if we set the file object to be unbuffered (`setvbuf(fd, NULL, _IONBF, 0);`) right after the file's opening * Stepping through gdb, I came to an infinite cycle in glibc/libio/genops.c#underflow and glibc/libio/iogetdelim.c#_IO_getdelim . When the last line of the file is reached, an underflow calculation is done in iogetdelim and an execution path sets the flags of the file to _IO_EOF_SEEN, which getline (seems) to ignore and thinking that the file cache is invalidated starts over. I don't know how much this will help. Found by: Yuxuan Ren <yre...@illinois.edu> Confirmation Testing/Validation: Lawrence Angrave <angr...@illinois.edu> ** Affects: glibc (Ubuntu) Importance: Undecided Status: New ** Tags: getline -- You received this bug notification because you are a member of Ubuntu Bugs, which is subscribed to Ubuntu. https://bugs.launchpad.net/bugs/1750173 Title: getline doesn't terminate after fork To manage notifications about this bug go to: https://bugs.launchpad.net/ubuntu/+source/glibc/+bug/1750173/+subscriptions -- ubuntu-bugs mailing list ubuntu-bugs@lists.ubuntu.com https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs