try/catch around constructor super.<init> (after 8167104)

harold seigel harold.seigel at oracle.com
Thu Jan 26 20:59:32 UTC 2017


Hi Michael,

Thank you for your email.

It is no longer possible to have an exception handler that covers 
"invokespecial <init>" because of integrity reasons.

Please contact Alex Buckley (JVM Spec lead) directly at 
alex.buckley at oracle.com if you have follow up questions concerning this 
issue.

Thanks, Harold


On 1/26/2017 7:26 AM, Michael Rasmussen wrote:
> Hi
>
> After the fix[1] for 8167104, it is no longer possible to have a
> try/catch around the super <init> invocation, since flags are compared
> as well, but verify_exception_handler_targets is called with this_uninit
> set and with type resolved.
>
> The fix broke around/tracing adapters for constructors.
>
> previously something like this worked well:
> frame[{uninitialized_this}, {}]
> try
>    aload_0
>    invokespecial super.<init>
>    /* body */
>    return
> end try
>
> frame[{top}, {Throwable}]
> catch
>    athrow
>
> Looking at the JVMS, the above do violate the stack frame verification,
> stating subset(Flags1, Flags2), which the patch fixed.
>
> But modifying the above code to the below also fails:
> frame[{uninitialized_this}, {}]
> try #1
>    aload_0
>    invokespecial super.<init>
> end try #1
> try #2 // frame[{this}, {}]
>    /* body */
>    return
> end try #2
>
> frame[{uninitialized_this}, {Throwable}]
> catch #1
>    athrow
>
> frame[{top}, {Throwable}]
> catch #2
>    athrow
>
> Based on a quick peek, it seems when verifying the invokespecial opcode
> that verify_exception_handler_targets is called inside verify_invoke_init
> before the type is resolved using initialize_object, including a comment
> that states that it should be done here before initialize_object. But,
> verify_exception_handler_targets is called again, after initialize_object
> has changed the type, from after the switch-block in verify_method, with
> this_uninit set to true.
>
> This causes an error, with the following details:
> VerifyError: Stack map does not match the one at exception handler 6
>
> Exception Details:
>    Location:
>      com/test/TraceConstructor.<init>()V @6: athrow
>    Reason:
>      Type 'com/test/TraceConstructor' (current frame, locals[0]) is not
>      assignable to uninitializedThis (stack map, locals[0])
>    Current Frame:
>      bci: @1
>      flags: { flagThisUninit }
>      locals: { 'com/test/TraceConstructor' }
>      stack: { 'java/lang/Throwable' }
>    Stackmap Frame:
>      bci: @6
>      flags: { flagThisUninit }
>      locals: { uninitializedThis }
>      stack: { 'java/lang/Throwable' }
>    Bytecode:
>      0x0000000: 2ab7 0008 b1bf bf
>    Exception Handler Table:
>      bci [4, 5] => handler: 5
>      bci [0, 4] => handler: 6
>    Stackmap Table:
>      same_frame(@0)
>      full_frame(@5,{Top},{Object[#10]})
>      full_frame(@6,{UninitializedThis},{Object[#10]})
>
> Kind regards
> Michael Rasmussen
> ZeroTurnaround
>
> [1] http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/rev/02a3d0dcbedd
> http://hg.openjdk.java.net/jdk9/jdk9/hotspot/rev/a9fdfd55835e



More information about the hotspot-dev mailing list