Re: lib/60324: unwind.h build race condition
"Robert Elz via gnats" <[email protected]>
| Newsgroups | gmane.os.netbsd.bugs |
|---|---|
| Message-ID | <[email protected]> |
The following reply was made to PR lib/60324; it has been noted by GNATS. From: Robert Elz <[email protected]> To: matthew green <[email protected]> Cc: [email protected], [email protected] Subject: Re: lib/60324: unwind.h build race condition Date: Thu, 09 Jul 2026 10:17:04 +0700 Date: Thu, 09 Jul 2026 11:11:26 +1000 From: matthew green <[email protected]> Message-ID: <[email protected]> | maybe the real fix is to not enter this subdirectory twice in | this same high-level .WAIT group at all. The issue with that, for me anyway, was still allowing users to cd to anywhere in the tree, and run "make" and have things work. If building libc doesn't (when needed) get the correct bits from libgcc (or whatever it was doing), then just cd src/lib/libc; make won't necessarily work. It should. And so should cd src/external/gpl3/gcc; make so both of those need to (at least be able to) descend into the part of the tree where the issue occurred (libgcov). | this isn't the only one, but maybe it's the only one that has | a build-a-file conflict. It might just be because of using ln -- most other commands would just replace whatever is there, whereas ln fails if the dest exists, it could be switched to use ln -f, but I doubt that's sufficient, it still ends up doing a symlink() call, just after (yet another) unlink() perhaps, but the two ln(1)'s both doing an unlink() if needed, followed by a symlink() in parallel are going to fail in just the same way - perhaps slightly less often as the sync between the two would need to be tighter. One possibility I thought of, but didn't try, would be to make the ln line of the relevant make recipe be (something like) ln -s ${.ALLSRC} ${.TARGET} || \ { X=$(readlink ${.TARGET}) && [ "$X" = "${.ALLSRC}" ] ; } converted into the correct make syntax ($$X for $X and the cmdsub etc) and with someone who knows how checking that the uses of TARGET and ALLSRC are correct. I didn't attempt that, as I never found where the relevant recipe appears (somewhere in share/mk I'd assume - a cesspit I like to avoid), and I'm also not sure that a change there like this would be OK for every possible use (if ever used to link multiple files into a directory, this wouldn't work at all). It also would mean needing readlink as a tool, which I doubt we have now (might need to be a specialised version, making stat(1) (which is what our readlink(1) really is) into a tool could be a challenge, but a very simple, portable, readlink(1), with limited abilities, just enough for this special case, should be easy enough). Or we could toolize ln, and give it a new option, that if set, and an EEXIST error is reported, would readlink(2) the existing file, and if that works, and the result is the same as the link that was to be created, to just treat that as OK, and not fail (which is more or less doing the above, internal to ln). (Might also want to do permission & ownership checks). | not doing this would mean we could take the new .WAIT away again. Perhaps. I'm not sure that would make any real difference, the build time for a full set of builds doesn't seem to have been altered, and for all the builds I checked (where the info is available without needing to do it myself!) the number of lines in the build logfile didn't change out of the range that had existed from recent previous builds, so I don't think adding that .WAIT really harmed anything - I had half expected the builds to take a bit longer, but they don't seem to have. Of course, it is also possible that the .WAIT is largely a no-op, but from what I could tell from my own test builds when I inserted it, it did seem to make (for each phase: obj, includes, dependall) the lib builds to be complete before the rest of the tree started. That's where I became confused, without the .WAIT there, what was stopping a dependall of (say) bin/cat from starting before the new lib/libc is available? If there is (was) nothing preventing that, how does (did) anything actually work? But clearly it all does, and did before, at least 99% of the time. kre ps: I am also still not convinced that the problem is fixed, it is likely that the cases I detected will no longer occur, but the same thing might be possible from a two parts of the tree not including "lib" - just perhaps even more rarely occurring.