Verifier error with try-finally clause in Java 1.7
---------------------------------------------------
Key: JASSIST-195
URL:
https://issues.jboss.org/browse/JASSIST-195
Project: Javassist
Issue Type: Bug
Affects Versions: 3.17.1-GA
Environment: Oracle Java 1.7 on Mac OS X
Reporter: John Brush
Assignee: Shigeru Chiba
Fix For: 3.18.0-GA
After upgrading from Java 1.6 to Java 1.7 our unit tests failed due to the new verifier
in 1.7 which requires a stack map. I fixed this issue by adding a call to the
rebuildStackMap() method after instrumentation, but this caused a new problem to pop up in
one particular instance:
{code}
public int testInstrumentedCallInFinallyBlock( int i )
{
try
{}
catch ( Throwable t )
{}
finally
{
i = incByOne( i );
}
return i;
}
{code}
This unit test results in the following exception:
java.lang.VerifyError: Stack map does not match the one at exception handler 9 in method
xxx.StatementsTestComponent.testInstrumentedCallInFinallyBlock(I)I at offset 9
After some investigation, I noticed that the problem occurred independent of my
instrumentation, simply as a result of loading the byte code with Javassist, invoking
rebuildStackMap() and then trying to load it. The byte code for the above snippet looks as
follows before invoking rebuildStackMap():
{code}
Code:
stack=2, locals=3, args_size=2
0: aload_0
1: iload_1
2: invokespecial #3 // Method incByOne:(I)I
5: istore_1
6: goto 18
9: astore_2
10: aload_0
11: iload_1
12: invokespecial #3 // Method incByOne:(I)I
15: istore_1
16: aload_2
17: athrow
18: iload_1
19: ireturn
Exception table:
from to target type
9 10 9 any
StackMapTable: number_of_entries = 2
frame_type = 73 /* same_locals_1_stack_item */
stack = [ class java/lang/Throwable ]
frame_type = 8 /* same */
{code}
Afterwards, it looks like this:
{code}
Code:
stack=2, locals=3, args_size=2
0: aload_0
1: iload_1
2: invokespecial #23 // Method incByOne:(I)I
5: istore_1
6: goto 18
9: nop
10: nop
11: nop
12: nop
13: nop
14: nop
15: goto 9
18: iload_1
19: ireturn
Exception table:
from to target type
9 10 9 any
StackMapTable: number_of_entries = 2
frame_type = 249 /* chop */
offset_delta = 9
frame_type = 253 /* append */
offset_delta = 8
locals = [ class
ch/shaktipat/saraswati/instrument/busicomp/StatementsTestComponent, int ]
{code}
Notice the modifications from lines 9-15: this is a result of Javassist's
MapMaker.fixDeadcode() method. I assume that the verify error is a result of the exception
table entry that refers to code which is no longer there. A possible fix would be to make
sure that any exception handlers referring to dead code are removed in such cases.
Personally, I would prefer that Javassist simply not modify the code if at all possible,
or at least for such modifications to be optional (configurable).
BTW: my only workaround for the time being is to force the 1.7 JVM to use the old
verifier with -XX:-UseSplitVerifier.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: