jspawnhelper's sometimes problematic use of argv0

Daniel Jarabek jarabekit at gmail.com
Sat Jun 17 04:33:42 UTC 2023


Hi,

While trying to run jshell in qemu-user-static using binfmt_misc 
(specifically, using this docker based tool [1]), I ran into an issue. 
Jshell would fail to start and print `This command is not for general 
use and should only be run as the result of a call to 
ProcessBuilder.start() or Runtime.exec() in a java application` along 
with a stack trace including `Failed to exec spawn helper`. After 
searching this error, I found JDK-8296001 [2]. This issue presented a 
very similar scenario (using a userspace architecture emulator). I 
looked into this issue and I believe I have identified the root cause.

My specific investigation was done around jdk17, but this issue also 
occurs on jdk20 and older jdk versions (though it seems like the "spawn" 
strategy is not used by default on linux with jdk 8 and 11).

Note: I use argv0 to refer to "argv[0]" to prevent confusion with footnotes.

Traditionally, argv0 contains the name of the program being executed. 
While this is more a convention than anything [3], it is very widely 
used. jspawnhelper [4] is an executable used to assist in launching 
processes via ProcessBuilder and Runtime.exec. Unlike the convention, 
jspawnhelper uses argv0 for passing data [5]. When binfmts_misc [6] 
executes an interpreter, it overwrites argv0, unless a flag is set. This 
causes jspawnhelper to fail to parse argv0 (since it's the application 
path, and not the data sent by the JDK), so it prints the warning about 
not being for general use. By setting the binfmt_misc `P` 
(preserve-argv0) flag, it preserves argv0 which fixes this problem.

Since qemu-user correctly supports this flag, all I had to do to fix the 
issue in my case was run qemu-binfmt-conf.sh with `--preserve-argv0 yes` 
to set that flag. It's likely that in the case of the above issue, the 
same problem is occurring and it may have a similar resolution. This 
could be fixed in OpenJDK by using argv1 instead, but at least in my 
case of binfmts_misc, this is an external configuration issue that can 
be easily fixed. However, I would appreciate it if someone with 
permission could comment on the above issue with a link to this email 
for anyone who runs into this in the future.

-DJ

[1] https://github.com/multiarch/qemu-user-static
[2] https://bugs.openjdk.org/browse/JDK-8296001
[3] https://stackoverflow.com/a/2051031
[4] 
https://github.com/openjdk/jdk/blob/master/src/java.base/unix/native/jspawnhelper/jspawnhelper.c
[5] 
https://github.com/openjdk/jdk/blob/bcc4d36857b0907e865d0afc4447f9b0780f8101/src/java.base/unix/native/libjava/ProcessImpl_md.c#L498-L500
[6] https://docs.kernel.org/admin-guide/binfmt-misc.html


More information about the core-libs-dev mailing list