RFR: Force setting LD_LIBRARY_PATH in launcher
David Holmes
david.holmes at oracle.com
Wed Apr 12 05:51:06 UTC 2017
On 12/04/2017 3:23 PM, Mikael Vidstedt wrote:
>
>> On Apr 11, 2017, at 8:55 PM, David Holmes <david.holmes at oracle.com> wrote:
>>
>> On 12/04/2017 12:35 PM, Mikael Vidstedt wrote:
>>>
>>> This one is a big tricky:
>>>
>>> http://cr.openjdk.java.net/~mikael/webrevs/portola/launcherfix/webrev.00/webrev/
>>> http://cr.openjdk.java.net/~mikael/webrevs/portola/launcherfix/webrev.00/jdk/webrev/
>>>
>>> The end goal is to get the launcher (java_md_solinux.c) to add the path to libjvm.so to LD_LIBRARY_PATH, but to only do so if running/building for musl. Here’s the comment I added to java_md_solinux.c, which hopefully explains why this is needed:
>>>
>>> /*
>>> * The musl library loader requires LD_LIBRARY_PATH to be set in
>>> * order to correctly resolve the dependency libjava.so has on libjvm.so.
>>
>> I had not realized that the dynamic loader was part of libc. I had assumed it was part of the OS proper.
>>
>>> *
>>> * Specifically, it differs from glibc in the sense that even if
>>> * libjvm.so has already been loaded it will not be considered a
>>> * candidate for resolving the dependency unless the *full* path
>>> * of the already loaded library matches the dependency being loaded.
>>> *
>>> * libjvm.so is being loaded by the launcher using a long path to
>>> * dlopen, not just the basename of the library. Typically this
>>> * is something like "../lib/server/libjvm.so". However, if/when
>>> * libjvm.so later tries to dlopen libjava.so (which it does in
>>> * order to get access to a few functions implemented in
>>> * libjava.so) the musl loader will, as part of loading
>>> * dependent libraries, try to load libjvm.so using only its
>>> * basename "libjvm.so". Since this does not match the longer
>>> * path path it was first loaded with, the already loaded
>>> * library is not considered a candidate, and the loader will
>>> * instead look for libjvm.so elsewhere. If it's not in
>>> * LD_LIBRARY_PATH the dependency load will fail, and libjava.so
>>> * will therefore fail as well.
>>> */
>>> Since there is no way to know at runtime that musl is being used, and there is no “system” compile time define to base the decision on, this change adds support to the JDK build system to set up a OPENJDK_{BUILD,TARGET}_CLIB variables based on the autoconf tuple, passing in the value to java_md_solinux.c as a compiler define -DCLIB=“…”, using that define to check for musl in RequiresSetenv, and returning true to force the setting of LD_LIBRARY_PATH if there’s a match.
>>
>> But we can infer we are using musl if we don't get any glibc version information.
>
>
> We could. I’m not a fan of having !glibc imply musl though. Like, at all. Not saying you can’t change my mind, but you’ll have to work on it :)
Until we support some other non-glibc library it seems like a pretty
safe bet!
But as discussed on IM the VM knowing it is on musl doesn't help. The
problem is that the launcher loaded a specific libjvm by path (client,
server, minimal) and libjava has a dependency on libjvm but with no
location info. libjvm is not in any of the ld search locations, hence
the musl loader won't find it, as it doesn't consider the already loaded
libjvm to be a candidate.
Short term solution - hack LD_LIBRARY_PATH in launcher.
BTW is what we are seeing with musl the same as what happens on AIX:
/* We always have to set the LIBPATH on AIX because ld doesn't support
$ORIGIN. */
??
Long term solution ... use a single unified DSO for java and the jvm
(and jli?) and dispense with JREs that contain multiple VMs.
Cheers,
David
> Cheers,
> Mikael
>
More information about the portola-dev
mailing list