Community
Participate
Working Groups
Build Identifier: 20110916-0149 When running attached Java class a "java.lang.VerifyError: Inconsistent stackmap frames" occurs. When compiling with javac all works as expected. Tried with * openjdk version "1.7.0-b213" and Eclipse 20110916-0149 on Mac OS X * java build 1.7.0-b147 and Eclipse 20110916-0149 on Windows 7 Class producing the error and stack trace is attached. Reproducible: Always Steps to Reproduce: 1. Create new Java project (Java 7) 2. Create attached class 3. Run it
Created attachment 205251 [details] Class producing error
Created attachment 205252 [details] Stack trace
I'll follow up.
This works in HEAD. Likely a dup of bug 359495.
(In reply to comment #4) > This works in HEAD. Likely a dup of bug 359495. That was what I thought, but I did manage to reproduce it on HEAD. I'll try again today to reconfirm.
(In reply to comment #5) > (In reply to comment #4) > > This works in HEAD. Likely a dup of bug 359495. > > That was what I thought, but I did manage to reproduce it on HEAD. > I'll try again today to reconfirm. I get a verify error with both IBM JVM and Sun JVM. If the resources section has only one resource or if the boolean foo was made non-final and initialized, then the verify error does not occur.
Can you provide a test case that is failing ?
(In reply to comment #7) > Can you provide a test case that is failing ? The test from comment# 0 fails for me with both IBM and Sun JREs. I'll ask Ayush to also test so we can eliminate some set up issue on my side. Ayush, can you please see if you can reproduce this ?
Ok, it fails if all locals are preserved. If unused locals are optimized out, the code generation is fine. Do you want me to take a look at this one?
The stack map table is too simple. I think the problem comes from the locals initialization ranges. Since the stack map frames are based on those ranges, it could explain why there is a problem.
(In reply to comment #9) > Ok, it fails if all locals are preserved. If unused locals are optimized out, > the code generation is fine. > Do you want me to take a look at this one? Sure, if you have the cycles that would be appreciated, given we are close to milestone builds. Thanks Olivier.
Another test case from bug 364008 public class Bug { public static void main(final String[] args) throws IOException { byte[] data; try (final ByteArrayOutputStream os = new ByteArrayOutputStream(); final FileOutputStream out = new FileOutputStream("test.dat")) { data = os.toByteArray(); } } }
*** Bug 364008 has been marked as a duplicate of this bug. ***
For posterity, here are some variously annotated notes that highlight the problem. The disassembler output has been annotated to show the effects of the transformation described in https://bugs.eclipse.org/bugs/show_bug.cgi?id=338402#c16 There are two things that sick out: (1) frame at 119 looks suspicious - where did the local int come from ? (2) edge from 52-119 obviously is problematic. Fix under investigation. Exception in thread "main" java.lang.VerifyError: JVMVRFY012 stack shape inconsistent; class=X, method=main([Ljava/lang/String;)V, pc=52 at java.lang.J9VMInternals.verifyImpl(Native Method) at java.lang.J9VMInternals.verify(J9VMInternals.java:90) at java.lang.J9VMInternals.initialize(J9VMInternals.java:167) Exception in thread "main" java.lang.VerifyError: Inconsistent stackmap frames a t branch target 119 in method X.main([Ljava/lang/String;)V at offset 52 at java.lang.Class.getDeclaredMethods0(Native Method) at java.lang.Class.privateGetDeclaredMethods(Class.java:2442) at java.lang.Class.getMethod0(Class.java:2685) at java.lang.Class.getMethod(Class.java:1620) at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:484) at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:476) Classfile /C:/jtests/X.class Last modified Nov 16, 2011; size 955 bytes MD5 checksum 0e58850442c5401c5e66d4aa9e656788 Compiled from "X.java" public class X implements java.lang.AutoCloseable SourceFile: "X.java" minor version: 0 major version: 51 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Class #2 // X #2 = Utf8 X #3 = Class #4 // java/lang/Object #4 = Utf8 java/lang/Object #5 = Class #6 // java/lang/AutoCloseable #6 = Utf8 java/lang/AutoCloseable #7 = Utf8 <init> #8 = Utf8 ()V #9 = Utf8 Code #10 = Methodref #3.#11 // java/lang/Object."<init>":()V #11 = NameAndType #7:#8 // "<init>":()V #12 = Utf8 LineNumberTable #13 = Utf8 LocalVariableTable #14 = Utf8 this #15 = Utf8 LX; #16 = Utf8 close #17 = Utf8 Exceptions #18 = Class #19 // java/lang/Exception #19 = Utf8 java/lang/Exception #20 = Methodref #18.#11 // java/lang/Exception."<init>":()V #21 = Utf8 main #22 = Utf8 ([Ljava/lang/String;)V #23 = Methodref #1.#11 // X."<init>":()V #24 = Methodref #1.#25 // X.close:()V #25 = NameAndType #16:#8 // close:()V #26 = Methodref #27.#29 // java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V #27 = Class #28 // java/lang/Throwable #28 = Utf8 java/lang/Throwable #29 = NameAndType #30:#31 // addSuppressed:(Ljava/lang/Throwable;)V #30 = Utf8 addSuppressed #31 = Utf8 (Ljava/lang/Throwable;)V #32 = Utf8 args #33 = Utf8 [Ljava/lang/String; #34 = Utf8 foo #35 = Utf8 Z #36 = Utf8 a #37 = Utf8 b #38 = Utf8 exception #39 = Utf8 Ljava/lang/Exception; #40 = Utf8 StackMapTable #41 = Class #33 // "[Ljava/lang/String;" #42 = Utf8 SourceFile #43 = Utf8 X.java { public static void main(java.lang.String[]); flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=6, args_size=1 0: aconst_null 1: astore_2 L2# _primaryExceptionVariable = null; 2: aconst_null 3: astore_3 L3# caughtThrowableVariable = null; 4: new #1 // class X 7: dup 8: invokespecial #23 // Method "<init>":()V 11: astore 4 a = new X(); 13: new #1 // class X 16: dup 17: invokespecial #23 // Method "<init>":()V 20: astore 5 b = new X(); ------------------ Try body as given by user ----- 22: iconst_1 23: istore_1 foo = true; -------------------- Auto close of b -------------- 24: aload 5 26: ifnull 50 29: aload 5 31: invokevirtual #24 // Method close:()V if (b != null) b.close(); 34: goto 50 ------------------ catch block -------------------- locals = [ class "[Ljava/lang/String;", top, class java/lang/Throwable, class java/lang/Throwable, class X, class X ] stack = [ class java/lang/Throwable ] 37: astore_2 L2# _primaryExceptionVariable = exceptionCaught. 38: aload 5 40: ifnull 48 43: aload 5 45: invokevirtual #24 // Method close:()V if (b != null) b.close(); locals = [ class "[Ljava/lang/String;", class java/lang/Throwable, class java/lang/Throwable, class X (a) ] stack [empty] 48: aload_2 49: athrow throw primaryException; ---------- Normal automatic resource closure for a ----------------- locals = [ class "[Ljava/lang/String;", class java/lang/Throwable, class java/lang/Throwable, class X (a) ] stack [empty] 50: aload 4 52: ifnull 119 55: aload 4 57: invokevirtual #24 // Method close:()V if (a != null) a.close(); 60: goto 119 ---------------------------------------------------------------------- locals = [ class "[Ljava/lang/String;", class java/lang/Throwable, class java/lang/Throwable, class X (a) ] stack = [ class java/lang/Throwable ] 63: astore_3 L3# caughtThrowableVariable = exceptionCaught 64: aload_2 65: ifnonnull 73 68: aload_3 69: astore_2 if (primaryException == null) primaryException = caughtThrowableVariable; 70: goto 83 -------------------------- Suppression list management ------------- locals = [ class "[Ljava/lang/String;", class java/lang/Throwable, class java/lang/Throwable, class X (a) ] stack = [ class java/lang/Throwable ] 73: aload_2 74: aload_3 75: if_acmpeq 83 78: aload_2 79: aload_3 80: invokevirtual #26 // Method java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V if (_primaryException != caughtThrowableVariable) { _primaryException.addSuppressed(caughtThrowableVariable); } ------------------------------------------------------------------------ locals = [ class "[Ljava/lang/String;", class java/lang/Throwable, class java/lang/Throwable, class X (a) ] stack = [ class java/lang/Throwable ] 83: aload 4 85: ifnull 93 88: aload 4 90: invokevirtual #24 // Method close:()V if (a != null) a.close(); ----------------------------------------------------- locals = [ class "[Ljava/lang/String;", class java/lang/Throwable, class java/lang/Throwable] stack = [ Empty ] 93: aload_2 94: athrow throw primaryException; ---------------------------------------------- locals = [ class "[Ljava/lang/String;", class java/lang/Throwable, class java/lang/Throwable] stack = [ class java/lang/Throwable ] 95: astore_3 L3# caughtThrowableVariable = exceptionCaught 96: aload_2 97: ifnonnull 105 100: aload_3 101: astore_2 if (primaryException == null) primaryException = caughtThrowableVariable; 102: goto 115 ----------------------------------------------------- locals = [ class "[Ljava/lang/String;", class java/lang/Throwable, class java/lang/Throwable] stack = [ class java/lang/Throwable ] 105: aload_2 106: aload_3 107: if_acmpeq 115 110: aload_2 111: aload_3 112: invokevirtual #26 // Method java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V if (_primaryException != caughtThrowableVariable) { _primaryException.addSuppressed(caughtThrowableVariable); } -------------------------------------------------------- locals = [ class "[Ljava/lang/String;", class java/lang/Throwable, class java/lang/Throwable] stack = [ class java/lang/Throwable ] 115: aload_2 116: athrow throw primaryException; ---------------------- User's catch block -------------------- locals = [ class "[Ljava/lang/String;" ] stack = [ class java/lang/Exception ] 117: astore_2 118: return --------------------------------------------------------------- locals = [ class "[Ljava/lang/String;" , int ] stack = [ EMPTY ] 119: return Exception table: from to target type 22 24 37 any 13 50 63 any 4 95 95 any 0 117 117 Class java/lang/Exception LocalVariableTable: Start Length Slot Name Signature 0 120 0 args [Ljava/lang/String; 24 13 1 foo Z 119 1 1 foo Z 13 80 4 a LX; 22 26 5 b LX; 118 1 2 exception Ljava/lang/Exception; StackMapTable: number_of_entries = 12 -------------------- frame_type = 255 /* full_frame */ offset_delta = 37 locals = [ class "[Ljava/lang/String;", top, class java/lang/Throwable, class java/lang/Throwable, class X, class X ] stack = [ class java/lang/Throwable ] -------------------- frame_type = 250 /* chop */ offset_delta = 10 ------------------- frame_type = 1 /* same */ ----------------------- frame_type = 76 /* same_locals_1_stack_item */ stack = [ class java/lang/Throwable ] ------------------------- frame_type = 9 /* same */ ------------------------- frame_type = 9 /* same */ -------------------------- frame_type = 250 /* chop */ offset_delta = 9 ----------------------------- frame_type = 65 /* same_locals_1_stack_item */ stack = [ class java/lang/Throwable ] ------------------------------ frame_type = 9 /* same */ ------------------------------- frame_type = 9 /* same */ ------------------------------- frame_type = 255 /* full_frame */ offset_delta = 1 locals = [ class "[Ljava/lang/String;" ] stack = [ class java/lang/Exception ] ---------------------------------- frame_type = 252 /* append */ offset_delta = 1 locals = [ int ] }
(In reply to comment #14) > For posterity, here are some variously annotated notes that highlight the > problem. The disassembler output has been annotated to show the effects of > the transformation described in > https://bugs.eclipse.org/bugs/show_bug.cgi?id=338402#c16 Just a note that the transformation referred to above is missing in null checks prior to close. (the generated code does the right thing)
(In reply to comment #14) > (1) frame at 119 looks suspicious - where did the local int come from ? int being vm type for boolean, it appears that we are claiming the boolean foo is in range after the twr - which is blatantly not true. Investigating the initialization ranges ...
Created attachment 207216 [details] Patch under test With this patch both the issues reported in current bug and its duplicate are fixed. Try*Tests pass, Running all JDT/Core tests now.
(In reply to comment #14) > There are two things that sick out: > > (1) frame at 119 looks suspicious - where did the local int come from ? This int local is indeed correct, I had missed that the catch block was returning. > (2) edge from 52-119 obviously is problematic. This is problematic and is fixed by the patch.
Passes all tests. Olivier, please review this small patch - TIA. Basically, given that the single try statement is getting transformed into several nested try-catch-finally blocks as described in bug 338402 comment 16, we need to reset the type states whenever we are fully done with a nested try block. Presently, it is left at the type state corresponding to the catch block of the nested try block.
Patch looks good. Local initialization ranges look better.
Released fix and tests in 3.8 stream via commit 7a907611eaa1f47df5cf7c04e21c82794b93d39a. Ayush, please also release for 3.7.2 and 3.6.2+java7 as this is a serious issue and has been reported from multiple sources.
Released in 3.7 maintenance via commit 7db712d6cc704573774e9fbd29d0c7b0d40d6d3c
Verified for 3.8M4 using build I20111202-0800
Released in 3.6.2+java7 branch via commit c07bf8c2ab7dee126a5194e2fc5ef6123e172c13
Verified for 3.7.2RC2 using build M20120118-0800