MethodHandle initialization process - problem with JVM TI early VM start event

Alan Bateman Alan.Bateman at oracle.com
Wed Jan 4 08:45:38 UTC 2017


On 04/01/2017 03:11, David Holmes wrote:

> We have encountered a crash in a JVM TI test, starting with b148, that 
> is caused by the attempted use of MethodRefs and invoke_dynamic within 
> class loading that occurs from the "early VM start" JVM TI event 
> callback - which happens before the VM and core classes are fully 
> initialized. The class being loaded/initialized is in java.base and so 
> this is allowed. The class, java.net.Authenticator, was changed in 
> b148 to have static initialization involving method refs and hence the 
> problem was introduced.
>
> I've included a stack dump below.
>
> It is far from clear to me where responsibility for this lies, or even 
> how to narrow that down. Is it in the code of MethodHandleNatives? Or 
> is it in the VM linking/resolution code?
>
> Thoughts appreciated. :)
Ugh, this looks like the callback for the VMStart event is triggering 
the execution of arbitrary code via its initializer. When the 
can_generate_early_vmstart capability is enabled then the VMStart event 
is posted before the system classes are initialized (before 
Threads::initialize_java_lang_classes is called). If the callbacks uses 
JNI FindClass to load classes in java.base (it's restricted to java.base 
in this phase) then it will trigger the execution of random bytecode 
with all sort of consequences. Even if the system classes are 
initialized then it can still cause all sorts of issues - e.g. 
triggering code in classes such as ResourceBundle and elsewhere that 
depend on the system class loader to be initialized. For the specific 
crash then it looks like MethodHandleNatives has asserts and so 
Class::desiredAssertionStatus will be invoked to test if assertions are 
enabled but, as I say, there are lots of other reasons that would cause 
random classes in java.base to fail when invoked before the system 
classes are initialized.

The reason this event is called so early is to allow native (not java) 
agents get other events during startup. Also it's not new that this 
event is posted before the system classes are initialized, you'll see 
the same with JDK 8 and older because VMStart was always posted very 
early. In JDK 9 then the VMStart is only posted early when the 
can_generate_early_vmstart capability is enabled. This chage.

As regards fixing this then I don't think it would be unreasonable to 
put some restrictions on what can be done in the VMStart callback when 
can_generate_early_vmstart capability is enabled. Maybe it could be just 
further re-wording of the paragraph on what can be done in this phase 
rather than trying to enforce it.

-Alan


More information about the core-libs-dev mailing list