On Fri, 6 Mar 2026 14:28:46 GMT, Roger Riggs <[email protected]> wrote:
> Separately, I've a report of failures on a JDK 21 and JDK 17 build on Ubuntu > 25-10 with the same tests in Basic.java failing though only with exitcode 1 > (not zero). That would be an older version of the launch protocol and > mechanism. > > ``` > testJDK_os.arch=amd64 > testJDK_os.name=Linux > testJDK_os.version=6.17.0-1003-oracle > ``` I believe I figured out what happens, but I would like to prove it. Its actually a funny bug: Let's say parent has only 1, 2, 3 open. We do ProcessBuilder.inheritIO().start(). Now lets say, childenv pipe gets 4 and 5, fail pipe gets 6 and 7. We do these dup2 actions in the child process after forking: https://github.com/openjdk/jdk/pull/29939/changes#diff-ffbcab6325b2ae4b57a81e39c51c155cb2dab372bc915060dfc47159c345797fR646-R647 We first dup2 fail[1] to "4". Now we have overwritten childenv[0], which now also points to the fail pipe write end. We then dup2 childenv[0] to "5", but it's actually the fail pipe write end we copy. So now, both 4 and 5 point to fail pipe write end. We try to read from 5 (the childenv[0]) in jspawnhelper to receive the ChildStuff structure from the parent. But since this is actually a copy of fail pipe write descriptor, I guess the read() fails immediately. So then we report "ERR_PIPE" via 4 (the real fail pipe write end), and this is what we see in the parent ("Failed.. (2)"). Whether this happens depends on luck, whether we get file descriptors <5 when creating a pipe. The old code did not do dup2 for fail and childenv, instead passing them via command line parameter. I kind of like the new way better, and will think about a way to circumvent the problem. ------------- PR Comment: https://git.openjdk.org/jdk/pull/29939#issuecomment-4012489335
