-XXaltjvm, dtruss and ASAN

Been a while since I’ve posted anything technical, but in any case it is good to be back! Aside from work, I hadn’t been doing any hacking on my own for a while, due to the lack of time and energy. So it’s a nice change for a break this year that I’ve finally gotten the motivation back to be developing for leisure again :)

The current little hack is simply a start from scratch project to build an alternative JVM runtime. The basis of this design will be based on what I’ve learnt from the DRLVM’s code base, and avoiding some of their design pitfalls that I’ve encountered with their code.

The additional challenge is that my new development environment is MacOSX - while UNIX-y enough, just simply does not have a number of the GNU tools which I miss (objcopy, ldd) and some new formats that I’m not familiar with (eg. Mach-O vs ELF) and some new tools that I have to Google to find the analogue equivalent of (eg. strace vs dtruss), but nothing insurmountable.

It’s been months since I’ve last touched VM’s code, and my rusty-ness shows, so this entry is more of an re-primer on how to load an alternative JVM runtime. This is one of those situations in which Googling works less well than code-diving, and the flag that I was after is -XXaltjvm=. This does not follow the -XX: semantics of the current day JVM, which is an indication of its age. os_bsd.cpp explains its use:


// Support for the java launcher's '-XXaltjvm=<path>' option. Typical
// value for buf is "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so"
// or "<JAVA_HOME>/jre/lib/<vmtype>/libjvm.dylib". If "/jre/lib/"
// appears at the right place in the string, then assume we are
// installed in a JDK and we're done. Otherwise, check for a
// JAVA_HOME environment variable and construct a path to the JVM
// being overridden.

With my lack of a creativity, I’ve decided to name my project runtime; hence the command line to use this would be -XXaltjvm=runtime. The JVM didn’t like a symlink, which I checked with dtruss:

% sudo dtruss ...

stat64("/Users/vincent.liu/repos/graal-exp/labsjdk1.8.0_111-jvmci-0.23/jre/lib/runtime/libjvm.|", 0x7FFF5AAAB408, 0x1000)       = -1 Err#2
write_nocancel(0x2, "Error: missing `runtime' JVM at `/Users/vincent.liu/repos/graal-exp/labsjdk1.8.0_111-jvmci-0.23/jre/lib/runtime/libjvm.dylib'.\nPlease install or use the JRE or JDK that contains these missing components|", 0xCB)               = 203 0

% ls -lah /Users/vincent.liu/repos/graal-exp/labsjdk1.8.0_111-jvmci-0.23/jre/lib/runtime/libjvm.dylib
lrwxr-xr-x  1 vincent.liu  44B Dec 24 07:46 /Users/vincent.liu/repos/graal-exp/labsjdk1.8.0_111-jvmci-0.23/jre/lib/runtime/libjvm.dylib -> runtime/build/runtime/src/.libs/libjvm.dylib

So the actual binary must be copied to the $JAVA_HOME path, which once after I’ve done that, I’m hitting it not finding the linked ASAN checks that I’ve compiled in:

Error: dl failure on line 674
Error: failed /Users/vincent.liu/repos/graal-exp/labsjdk1.8.0_111-jvmci-0.23/jre/lib/runtime/libjvm.dylib, because dlopen(/Users/vincent.liu/repos/graal-exp/labsjdk1.8.0_111-jvmci-0.23/jre/lib/runtime/libjvm.dylib, 10): Symbol not found: ___asan_init
Referenced from: /Users/vincent.liu/repos/graal-exp/labsjdk1.8.0_111-jvmci-0.23/jre/lib/runtime/libjvm.dylib
Expected in: flat namespace
in /Users/vincent.liu/repos/graal-exp/labsjdk1.8.0_111-jvmci-0.23/jre/lib/runtime/libjvm.dylib

No biggie, but I’ve got to stop to read more on how to deal with automake and libtool, all new things I’ve been learning. While autotools looks awfully complex, it’s still so much better than the old ‘Apache Ant’ build system!