Last active
January 3, 2017 23:20
-
-
Save rvprasad/e31260018b5513a4ed920b4e6519fa20 to your computer and use it in GitHub Desktop.
Code to reproduce bug 9046671 in JDK 8.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Run this with ASM 5.1 (http://forge.ow2.org/project/showfiles.php?group_id=23) to generate X.class. | |
* Loading the generated X.class will cause the following error with JDK 9-ea, JDK 1.8.0_112, and Zulu 1.8.0_112. | |
* | |
Error: A JNI error has occurred, please check your installation and try again | |
Exception in thread "main" java.lang.VerifyError: Stack map does not match the one at exception handler 13 | |
Exception Details: | |
Location: | |
X.<init>(LX;)V @13: athrow | |
Reason: | |
Current frame's flags are not assignable to stack map frame's. | |
Current Frame: | |
bci: @0 | |
flags: { flagThisUninit } | |
locals: { uninitializedThis, 'X' } | |
stack: { 'java/lang/Throwable' } | |
Stackmap Frame: | |
bci: @13 | |
flags: { } | |
locals: { top, 'X' } | |
stack: { 'java/lang/Throwable' } | |
Bytecode: | |
0000000: 2abb 0004 5906 b700 09b7 000c b1bf | |
Exception Handler Table: | |
bci [0, 13] => handler: 13 | |
Stackmap Table: | |
full_frame(@13,{Top,Object[#2]},{Object[#14]}) | |
at java.base/java.lang.Class.getDeclaredMethods0(Native Method) | |
at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:2996) | |
at java.base/java.lang.Class.privateGetMethodRecursive(Class.java:3340) | |
at java.base/java.lang.Class.getMethod0(Class.java:3310) | |
at java.base/java.lang.Class.getMethod(Class.java:1987) | |
at java.base/sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:672) | |
at java.base/sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:543) | |
* | |
*/ | |
import java.io.*; | |
import java.nio.file.Files; | |
import java.util.*; | |
import org.objectweb.asm.*; | |
import static org.objectweb.asm.Opcodes.*; | |
public class XDump { | |
public static void main(String[] s) throws Exception { | |
byte[] b = dump(); | |
Files.write(new File("./X.class").toPath(), b); | |
} | |
public static byte[] dump () throws Exception { | |
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); | |
FieldVisitor fv; | |
MethodVisitor mv; | |
AnnotationVisitor av0; | |
cw.visit(52, ACC_PUBLIC + ACC_SUPER, "X", null, "Y", null); | |
{ | |
mv = cw.visitMethod(0, "<init>", "(Ljava/lang/String;)V", null, null); | |
mv.visitCode(); | |
Label begin = new Label(); | |
mv.visitLabel(begin); | |
mv.visitVarInsn(ALOAD, 0); | |
mv.visitTypeInsn(NEW, "Y"); | |
mv.visitInsn(DUP); | |
mv.visitInsn(ICONST_3); | |
mv.visitMethodInsn(INVOKESPECIAL, "Y", "<init>", "(I)V", false); | |
mv.visitMethodInsn(INVOKESPECIAL, "Y", "<init>", "(Ljava/lang/Object;)V", false); | |
mv.visitInsn(RETURN); | |
Label end = new Label(); | |
mv.visitLabel(end); | |
mv.visitTryCatchBlock(begin, end, end, "java/lang/Throwable"); | |
mv.visitInsn(Opcodes.ATHROW); | |
mv.visitMaxs(4, 2); | |
mv.visitEnd(); | |
} | |
{ | |
mv = cw.visitMethod(0, "<init>", "(LX;)V", null, null); | |
mv.visitCode(); | |
Label begin = new Label(); | |
mv.visitLabel(begin); | |
mv.visitVarInsn(ALOAD, 0); | |
mv.visitTypeInsn(NEW, "Y"); | |
mv.visitInsn(DUP); | |
mv.visitInsn(ICONST_3); | |
mv.visitMethodInsn(INVOKESPECIAL, "Y", "<init>", "(I)V", false); | |
mv.visitMethodInsn(INVOKESPECIAL, "Y", "<init>", "(Ljava/lang/Object;)V", false); | |
mv.visitInsn(RETURN); | |
Label end = new Label(); | |
mv.visitLabel(end); | |
mv.visitTryCatchBlock(begin, end, end, "java/lang/Throwable"); | |
mv.visitInsn(Opcodes.ATHROW); | |
mv.visitMaxs(4, 2); | |
mv.visitEnd(); | |
} | |
cw.visitEnd(); | |
return cw.toByteArray(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* The above issue can be addressed by splitting the try-catch handler as done here. | |
*/ | |
import java.io.*; | |
import java.nio.file.Files; | |
import java.util.*; | |
import org.objectweb.asm.*; | |
import static org.objectweb.asm.Opcodes.*; | |
public class XDump2 { | |
public static void main(String[] s) throws Exception { | |
byte[] b = dump(); | |
Files.write(new File("./X.class").toPath(), b); | |
} | |
public static byte[] dump () throws Exception { | |
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); | |
FieldVisitor fv; | |
MethodVisitor mv; | |
AnnotationVisitor av0; | |
cw.visit(52, ACC_PUBLIC + ACC_SUPER, "X", null, "Y", null); | |
{ | |
mv = cw.visitMethod(0, "<init>", "(Ljava/lang/String;)V", null, null); | |
mv.visitCode(); | |
Label begin = new Label(); | |
mv.visitLabel(begin); | |
mv.visitVarInsn(ALOAD, 0); | |
mv.visitTypeInsn(NEW, "Y"); | |
mv.visitInsn(DUP); | |
mv.visitInsn(ICONST_3); | |
mv.visitMethodInsn(INVOKESPECIAL, "Y", "<init>", "(I)V", false); | |
mv.visitMethodInsn(INVOKESPECIAL, "Y", "<init>", "(Ljava/lang/Object;)V", false); | |
mv.visitInsn(RETURN); | |
Label end = new Label(); | |
mv.visitLabel(end); | |
mv.visitTryCatchBlock(begin, end, end, "java/lang/Throwable"); | |
mv.visitInsn(Opcodes.ATHROW); | |
mv.visitMaxs(4, 2); | |
mv.visitEnd(); | |
} | |
{ | |
mv = cw.visitMethod(0, "<init>", "(LX;)V", null, null); | |
mv.visitCode(); | |
Label begin1 = new Label(); | |
mv.visitLabel(begin1); | |
mv.visitVarInsn(ALOAD, 0); | |
mv.visitTypeInsn(NEW, "Y"); | |
mv.visitInsn(DUP); | |
mv.visitInsn(ICONST_3); | |
mv.visitMethodInsn(INVOKESPECIAL, "Y", "<init>", "(I)V", false); | |
Label end1 = new Label(); | |
mv.visitLabel(end1); | |
mv.visitMethodInsn(INVOKESPECIAL, "Y", "<init>", "(Ljava/lang/Object;)V", false); | |
Label begin2 = new Label(); | |
mv.visitLabel(begin2); | |
mv.visitInsn(RETURN); | |
Label end2 = new Label(); | |
mv.visitLabel(end2); | |
Label handler1 = new Label(); | |
mv.visitLabel(handler1); | |
mv.visitTryCatchBlock(begin1, end1, handler1, "java/lang/Throwable"); | |
mv.visitInsn(Opcodes.ATHROW); | |
Label handler2 = new Label(); | |
mv.visitLabel(handler2); | |
mv.visitTryCatchBlock(begin2, end2, handler2, "java/lang/Throwable"); | |
mv.visitInsn(Opcodes.ATHROW); | |
mv.visitMaxs(4, 2); | |
mv.visitEnd(); | |
} | |
cw.visitEnd(); | |
return cw.toByteArray(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* The above issue goes away if X's constructor does not have a parameter that is a sub-type of X. | |
*/ | |
import java.io.*; | |
import java.nio.file.Files; | |
import java.util.*; | |
import org.objectweb.asm.*; | |
import static org.objectweb.asm.Opcodes.*; | |
public class XDump3 { | |
public static void main(String[] s) throws Exception { | |
byte[] b = dump(); | |
Files.write(new File("./X.class").toPath(), b); | |
} | |
public static byte[] dump () throws Exception { | |
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); | |
FieldVisitor fv; | |
MethodVisitor mv; | |
AnnotationVisitor av0; | |
cw.visit(52, ACC_PUBLIC + ACC_SUPER, "X", null, "java/lang/Object", null); | |
{ | |
mv = cw.visitMethod(0, "<init>", "(Ljava/lang/String;)V", null, null); | |
mv.visitCode(); | |
Label begin = new Label(); | |
mv.visitLabel(begin); | |
mv.visitTypeInsn(NEW, "Y"); | |
mv.visitInsn(ICONST_3); | |
mv.visitMethodInsn(INVOKESPECIAL, "Y", "<init>", "(I)V", false); | |
mv.visitVarInsn(ALOAD, 0); | |
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); | |
mv.visitInsn(RETURN); | |
Label end = new Label(); | |
mv.visitLabel(end); | |
mv.visitTryCatchBlock(begin, end, end, "java/lang/Throwable"); | |
mv.visitInsn(Opcodes.ATHROW); | |
mv.visitMaxs(4, 2); | |
mv.visitEnd(); | |
} | |
{ | |
mv = cw.visitMethod(0, "<init>", "(LY;)V", null, null); | |
mv.visitCode(); | |
Label begin = new Label(); | |
mv.visitLabel(begin); | |
mv.visitTypeInsn(NEW, "Y"); | |
mv.visitInsn(ICONST_3); | |
mv.visitMethodInsn(INVOKESPECIAL, "Y", "<init>", "(I)V", false); | |
mv.visitVarInsn(ALOAD, 0); | |
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); | |
mv.visitInsn(RETURN); | |
Label end = new Label(); | |
mv.visitLabel(end); | |
mv.visitTryCatchBlock(begin, end, end, "java/lang/Throwable"); | |
mv.visitInsn(Opcodes.ATHROW); | |
mv.visitMaxs(4, 2); | |
mv.visitEnd(); | |
} | |
cw.visitEnd(); | |
return cw.toByteArray(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Run this with ASM 5.1 (http://forge.ow2.org/project/showfiles.php?group_id=23) to generate X.class. | |
*/ | |
import java.util.*; | |
import org.objectweb.asm.*; | |
public class YDump implements Opcodes { | |
public static void main(String[] s) throws Exception { | |
byte[] b = dump(); | |
Files.write(new File("./Y.class").toPath(), b); | |
} | |
public static byte[] dump () throws Exception { | |
ClassWriter cw = new ClassWriter(0); | |
FieldVisitor fv; | |
MethodVisitor mv; | |
AnnotationVisitor av0; | |
cw.visit(52, ACC_SUPER, "Y", null, "java/lang/Object", null); | |
{ | |
mv = cw.visitMethod(0, "<init>", "(Ljava/lang/Object;)V", null, null); | |
mv.visitCode(); | |
mv.visitVarInsn(ALOAD, 0); | |
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); | |
mv.visitInsn(RETURN); | |
mv.visitMaxs(1, 2); | |
mv.visitEnd(); | |
} | |
{ | |
mv = cw.visitMethod(0, "<init>", "(I)V", null, null); | |
mv.visitCode(); | |
mv.visitVarInsn(ALOAD, 0); | |
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); | |
mv.visitInsn(RETURN); | |
mv.visitMaxs(1, 2); | |
mv.visitEnd(); | |
} | |
cw.visitEnd(); | |
return cw.toByteArray(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment