URL: <http://savannah.gnu.org/bugs/?39934>
Summary: make closes a wrong FD, results in *** INTERNAL: readdir: Bad file descriptor Project: make Submitted by: pmachata Submitted on: Втр 03 Сен 2013 17:44:02 Severity: 3 - Normal Item Group: Bug Status: None Privacy: Public Assigned to: None Open/Closed: Open Discussion Lock: Any Component Version: SCM Operating System: None Fixed Release: None Triage Status: None _______________________________________________________ Details: This was filed in Red Hat bugzilla here: https://bugzilla.redhat.com/show_bug.cgi?id=885474 To reproduce this, use the following Makefile: default: /home/petr/src/make/build/make -f Makefile2 And the following Makefile2 (note: the path in vpath must exist): vpath %.c /home/petr/ foo: Then run make: $ make -j 2 /home/petr/src/make/build/make -f Makefile2 make[1]: Entering directory `/home/petr/tmp/tst' make[1]: warning: jobserver unavailable: using -j1. Add `+' to parent make rule. make[1]: *** INTERNAL: readdir: Bad file descriptor . Stop. make[1]: Makefile2: Field 'stem' not cached: Makefile2 make[1]: Leaving directory `/home/petr/tmp/tst' make: *** [default] Error 2 The following excerpt from an ltrace run illustrates the problem: 18706 16:46:43.945567 opendir("/home/petr" <unfinished ...> 18706 16:46:43.945713 SYS_open("/home/petr", 591872, 0172204710) = 4 18706 16:46:43.945785 SYS_brk(0) = 0x1e9d000 18706 16:46:43.945824 SYS_brk(0x1ec5000) = 0x1ec5000 18706 16:46:43.945870 <... opendir resumed> ) = { 4 } [...] 18706 16:46:44.347777 close(4 <unfinished ...> 18706 16:46:44.347882 SYS_close(4) = 0 18706 16:46:44.347927 <... close resumed> ) = 0 [...] 18706 16:46:45.718922 readdir({ 4 } <unfinished ...> 18706 16:46:45.719037 SYS_getdents(4, 0x161f008, 32768) = -9 18706 16:46:45.719103 <... readdir resumed> ) = 0 The problem arises when parental make passes down jobserver FDs in the environment, but the child make is not run as part of this jobsever batch. Child make notices JOB_FDS numbers passed down, and tries to dup, which fails, because JOB_FDS[0] is invalid. In then switches to -j1, and proceeds to close JOB_FDS. But in the meantime make managed to reuse one of those descriptors for a directory stream for vpath. When that is closed it later causes the error message seen in the subject. The immediate idea is not to close JOB_FDS if the dup fails. That's certainly part of the solution (because otherwise we end up calling close over invalid file descriptors). But that it fails is pure luck: make gets FD 3 for Makefile2, then FD 4 for vpath dirstream, and then closes 3 after it's done with it. Had --jobserver-fds been 4 and 5, we would dup it without trouble. But perhaps it's possible to move read_all_makefiles down beyond the JOB_FDS business. Then there would be no file operations except those in the dynamic linker, and those don't leak descriptors. Then we can use the dup as a reliable test. However I don't know whether there are interactions that I don't see, and whether it's safe and desirable to postpone the parsing to a later time like this. The test suite passes with this FWIW. _______________________________________________________ File Attachments: ------------------------------------------------------- Date: Втр 03 Сен 2013 17:44:02 Name: 0001-Don-t-close-JOB_FDS-if-we-know-they-are-invalid.patch Size: 2kB By: pmachata A fix <http://savannah.gnu.org/bugs/download.php?file_id=28997> _______________________________________________________ Reply to this item at: <http://savannah.gnu.org/bugs/?39934> _______________________________________________ Message sent via/by Savannah http://savannah.gnu.org/ _______________________________________________ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make