On Sunday, April 14, 2019 at 8:16:04 PM UTC-4, Waldek Kozaczuk wrote:
>
> Being able to run jvm without a wrapper is pretty significant (I guest it
> was possible as of over 4 years ago when support for running pies in OSv
> was added). We do not need all this related baggage anymore. Even now
> wrapper has some limiting preventing certain java 9 and up apps from
> running due to inadequate support of new options.
>
> In my other email I also mentioned I was able to run Python 2 as is
> without having to compile the main executable like in python2x app.
>
> On Sunday, April 14, 2019 at 6:03:37 PM UTC-4, Nadav Har'El wrote:
> > On Sun, Apr 14, 2019 at 11:21 PM Waldek Kozaczuk <[email protected]>
> wrote:
> >
> > As I was researching OSv ability to run unmodified Linux pie as is from
> host I did quick experiment with Java 8.
> >
> >
> > I created an app that took all java 8 artifacts as is from host (so no
> wrapper):
> >
> >
> >
> > cat usr.manifest
> > /usr/lib/jvm/java-8-openjdk-amd64/jre/**:
> /usr/lib/jvm/java-8-openjdk-amd64/jre/**
> > /usr/lib/libjli.so: ->
> /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/jli/libjli.so
> > /Hello.class: ${MODULE_DIR}/Hello.classand I was able to run it with two
> caveats
> >
> >
> > 1. After executing java apps OSv did not terminate and after I connected
> with gdb and some Java threads were stuck like this:
> >
> >
> >
> > (gdb) bt
> > #0 sched::thread::switch_to (this=0xffff800000aa7040,
> this@entry=0xffff800001e73040) at arch/x64/arch-switch.hh:108
> > #1 0x00000000003fd104 in sched::cpu::reschedule_from_interrupt
> (this=0xffff80000096b040,
> > called_from_yield=called_from_yield@entry=false, preempt_after=...,
> preempt_after@entry=...) at core/sched.cc:339
> > #2 0x00000000003fd5fc in sched::cpu::schedule () at
> include/osv/sched.hh:1309
> > #3 0x00000000003fdd22 in sched::thread::wait
> (this=this@entry=0xffff800002f87040) at core/sched.cc:1214
> > #4 0x00000000003e096f in
> sched::thread::do_wait_until<sched::noninterruptible,
> sched::thread::dummy_lock, waiter::wait(sched::timer*)
> const::{lambda()#1}>(sched::thread::dummy_lock&,
> waiter::wait(sched::timer*) const::{lambda()#1}) (pred=...,
> > mtx=<synthetic pointer>...) at include/osv/sched.hh:938
> > #5 sched::thread::wait_until<waiter::wait(sched::timer*)
> const::{lambda()#1}>(waiter::wait(sched::timer*) const::{lambda()#1})
> (pred=...) at include/osv/sched.hh:1076
> > #6 waiter::wait (tmr=0x0, this=0x2000105ce670) at
> include/osv/wait_record.hh:46
> > #7 condvar::wait (this=0xffffa00002c61280,
> user_mutex=0xffffa00002c5b140, tmr=<optimized out>) at core/condvar.cc:43
> > #8 0x0000100000c9842b in
> SharedRuntime::generate_native_wrapper(MacroAssembler*, methodHandle, int,
> BasicType*, VMRegPair*, BasicType) ()
> > #9 0x0000100000c8036d in
> SharedRuntime::throw_StackOverflowError(JavaThread*) ()
> > #10 0x0000000000000000 in ?? ()
> > I wonder if that is similar to why we have special logic to terminate
> all java threads in wrapper (java.cc). Ctrl-C does not work.
> >
> >
> > Yes. The code at the end of java.cc explains why it's needed:
> >
> >
> > // Unfortunately, Java's jvm->DestroyJavaVM() doesn't fully clean
> up, and
> > // leaves behind some detached threads such as GC threads and
> compilation
> > // threads. If we return with those still existing, loader.cc will
> wait
> > // (using application::join()) in vain for these threads to finish.
> > // So let's stop these threads. This call is unsafe, in the sense we
> > // assume that those renegade threads are not holding any critical
> > // resources (e.g., not in the middle of I/O or memory allocation).
> > while(!osv::application::unsafe_stop_and_abandon_other_threads()) {
> > usleep(100000);
> > }
> >
> >
> >
> > The thing is that when loader.cc runs an application it, deliberately,
> doesn't just wait for the main() function to return - it also waits for any
> other threads that the application started to finish as well. But in Java,
> there is simply no way to close these extra threads (such as Java GC
> threads). This is really a bug in Java, but it does make one wonder why OSv
> needs to be that pedantic about it. We could have a run option to just run
> main() and shut down once main() returns, without caring about any other
> threads (and of course without being able to run another application after
> this one
>
>
> Sounds like a great idea. I will try to come up with a patch at some
> point.
> >
> >
> >
> >
> >
> >
> >
> >
> > 2. I believe there is a bug in elf.cc::program::load_object() where I
> had to hack it to force finding and loading one of the shared object java
> pie executable depended on (all other so loaded fine). There may be
> actually 2 bugs:
> > there is a bug that prevents loading libjli.so by java pie; adding this
> nasty hack worked:
> >
> >
> >
> > @@ -1149,6 +1150,9 @@ std::shared_ptr<elf::object>
> > program::load_object(std::string name, std::vector<std::string>
> extra_path,
> > std::vector<std::shared_ptr<object>> &loaded_objects)
> > {
> > + if( name == "libjli.so" ) {
> > + name =
> "/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/jli/libjli.so";
> > + }
> > fileref f;
> >
> >
> > Let's see how this is supposed to work:
> >
> >
> >
> > libjli.so is needed by jre/lib/amd64/libinstrument.so. On my host
> (Fedora 29),
> >
> >
> > $ ldd /usr/lib/jvm/java-1.8.0-openjdk/jre/lib/amd64/libinstrument.so
> > linux-vdso.so.1 (0x00007ffec512e000)
> > libz.so.1 => /lib64/libz.so.1 (0x00007fcd91ac0000)
> > libjli.so =>
> /usr/lib/jvm/java-1.8.0-openjdk/jre/lib/amd64/jli/libjli.so
> (0x00007fcd91aae000)
> > libdl.so.2 => /lib64/libdl.so.2 (0x00007fcd91aa8000)
> > libc.so.6 => /lib64/libc.so.6 (0x00007fcd918e2000)
> > libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fcd918c0000)
> > /lib64/ld-linux-x86-64.so.2 (0x00007fcd91b28000)
> >
> >
> >
> > How did it find the pathname of libjli.so? Well,
> >
> >
> >
> > $ readelf -a
> /usr/lib/jvm/java-1.8.0-openjdk/jre/lib/amd64/libinstrument.so
> > ...
> > 0x0000000000000001 (NEEDED) Shared library: [libz.so.1]
> > 0x0000000000000001 (NEEDED) Shared library: [libjli.so]
> > 0x0000000000000001 (NEEDED) Shared library: [libdl.so.2]
> > 0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
> > 0x000000000000000e (SONAME) Library soname:
> [libinstrument.so]
> > 0x000000000000000f (RPATH) Library rpath:
> [$ORIGIN:$ORIGIN/jli]
> >
> >
> >
> > This RPATH asks when loading
> /usr/lib/jvm/java-1.8.0-openjdk/jre/lib/amd64/libinstrument.so and
> searching for "libjli.so" to also search for it in $ORIGIN/jli, i.e.,
> /usr/lib/jvm/java-1.8.0-openjdk/jre/lib/amd64/jli. Where it indeed is.
> >
> >
> > And we do have proper handling of DT_RPATH in core/elf.cc.
> >
> >
> > So either we have a bug in that RPATH handling that wasn't apparent to
> me now when I reviewed the code (and to Avi Kivity when he wrote it), or
> there's a different problem. Maybe me installed libjli.so at the wrong
> tree? Maybe if you add printouts to core/elf.cc's handling of DT_RPATH you
> can see more clearly what's the bug.
> I will try to figure it out. Hopefully something simple.
>
It has to do with the fact that I am executing is a symlink to real
executable:
/java ->
/usr/lib/jvm/jdk-zulu11.31.11-ca-jdk11.0.3-linux_x64-java-base/bin/java
So if I execute this:
/scripts/run.py -e
'/usr/lib/jvm/jdk-zulu11.31.11-ca-jdk11.0.3-linux_x64-java-base/bin/java
--version'
it works.
If I execute this:
/scripts/run.py -e '/java --version'
it fails as I described in my original error.
Here is the dynamic section of java:
Dynamic section at offset 0x1018 contains 30 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libz.so.1]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
*0x0000000000000001 (NEEDED) Shared library: [libjli.so]*
0x0000000000000001 (NEEDED) Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
*0x000000000000000f (RPATH) Library rpath:
[$ORIGIN/../lib/jli:$ORIGIN/../lib]*
...
and this part of the host file system (which is the same as on OSv FS):
/usr/lib/jvm/jdk-zulu11.31.11-ca-jdk11.0.3-linux_x64-java-base/lib/jli/libjli.so
/usr/lib/jvm/jdk-zulu11.31.11-ca-jdk11.0.3-linux_x64-java-base/bin/java
/java ->
/usr/lib/jvm/jdk-zulu11.31.11-ca-jdk11.0.3-linux_x64-java-base/bin/java
It works on Linux so I guess there is a way to fix it.
>
> >
> >
> >
> > there is a bug that silently ignores the fact that shared file has not
> been loaded and ends up OSv report this:
> > For historic reasons, OSv prints missing DT_NEEDED messages with
> debug():
> >
> >
> > debug("could not load %s\n", lib);
> >
> >
> > This means that unless you run with --verbose, you'll never see these
> messages...
> >
> > Hiding these messages was convenient in the past, and sometimes still is
> (see https://github.com/cloudius-systems/osv/issues/601) but maybe it
> makes sense to convert this message to a debug_always(), so it is always
> shown?
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> > /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java: failed looking up symbol
> JLI_Launch
> >
> >
> > [backtrace]
> > 0x000000000035cb8d <elf::object::symbol(unsigned int, bool)+1325>
> > 0x000000000035cc4f <elf::object::resolve_pltgot(unsigned int)+127>
> > 0x000000000035ce29 <elf_resolve_pltgot+57>
> > 0x00000000003a2d1f <???+3812639>
> > 0x00002000001ffe9f <???+2096799>
> > 0x000000000042e97c <osv::application::run_main()+60>
> > 0x000000000042eaae <__libc_start_main+46>
> > 0x00001000000060c9 <???+24777>
> >
> >
> > I also ran more complicated examples like vertx REST service one and it
> worked perfectly.
> >
> >
> > Waldek
> >
> >
> >
> >
> > --
> >
> > You received this message because you are subscribed to the Google
> Groups "OSv Development" group.
> >
> > To unsubscribe from this group and stop receiving emails from it, send
> an email to [email protected].
> >
> > For more options, visit https://groups.google.com/d/optout.
>
>
--
You received this message because you are subscribed to the Google Groups "OSv
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/osv-dev/d768b6be-ffa2-4391-abeb-6b558493e299%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.