Hi Thomas,

Thank you for this quick fix!

I have tested (after much difficultly getting cross compilation to work - a good learning experience) and this fix works for me. Using QEMU_STRACE, I verified that argv[0] is now the program name and argv[1] contains the fd data.

While you are correct, that changes to jspawnhelper aren't needed (since it uses argv[argc-1]), you may want to update this comment here: https://github.com/openjdk/jdk/blob/959a61fdd483c9523764b9ba0972f59ca06db0ee/src/java.base/unix/native/jspawnhelper/jspawnhelper.c#L139

-DJ

On 6/17/2023 16:43, Thomas Stüfe wrote:
Mind testing https://github.com/openjdk/jdk/pull/14531 ?

On Sat, Jun 17, 2023 at 8:20 PM Thomas Stüfe <thomas.stu...@gmail.com> wrote:

    Hi Daniel,

    thank you for that thorough analysis. I opened
    https://bugs.openjdk.org/browse/JDK-8310265 to track this issue.

    Looking at the code, this should be easy to fix, we would not even
    have to fix jspawnhelper itself, just its spawn point.

    I did a small patch which seemed to work. But this code is
    notorious for being tricky and I may overlooking something. Lets see.

    Cheers, Thomas





    On Sat, Jun 17, 2023 at 6:33 AM Daniel Jarabek
    <jarabe...@gmail.com> wrote:

        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

Reply via email to