Two verification missings
David Holmes
david.holmes at oracle.com
Thu Jun 25 04:18:35 UTC 2015
On 25/06/2015 8:22 AM, Yuting Chen wrote:
> Can anyone help me check whether some errors should be reported by
> Hotspots? The two classes are also attached.
>
> I generated some Java classes from SOOT's Jimple's code. When I re-checked
> the code, I noticed that two classes are absolutely not correct. I'd expect
> that some errors (e.g., VerifyError) could be thrown during the operations
> of the JVMs, but they are not. Can anyone tell me the reasons?
>
> Case 1: A VerifyError is caught by GCJ-Java, but missed by Hotspot.
> However, the type-casting between java.lang.String and java.util.Map may be
> unsafe. Verification results: (a) Hotspot 7/8/9: OK; (b) GCJ-Java JVM
> (1.5.0): Exception in ... Caused by: java.lang.VerifyError: verification
> failed at PC 1 in M1433982529S:internalTransform((Ljava.lang.String;)V):
> incompatible type on stack ...
Can't comment on this part.
> The Jimple's code.
> public class M1433982529S extends java.lang.Object
> {
> protected void internalTransform(java.lang.String)
> {
> java.util.Map r0;
>
> r0 := @parameter0: java.util.Map;
> staticinvoke <java.lang.Object: boolean
> getBoolean(java.util.Map)>(r0);
>
> return;
> }
> }
>
> Decompile the class: javap -verbose M1433982529S
> public class M1433982529S
> minor version: 0
> major version: 46
> flags: ACC_PUBLIC, ACC_SUPER
> Constant pool:
> #1 = Utf8 java/lang/Object
> #2 = Utf8 SourceFile
> #3 = Utf8 main
> #4 = Methodref #15.#13 //
> java/lang/Object.getBoolean:(Ljava/util/Map;)Z
> #5 = Utf8 Code
> #6 = Class #12 // M1433982529S
> #7 = Utf8 getBoolean
> #8 = Utf8 ([Ljava/lang/String;)V
> #9 = Utf8 Jasmin
> #10 = Utf8 internalTransform
> #11 = Utf8 (Ljava/util/Map;)Z
> #12 = Utf8 M1433982529S
> #13 = NameAndType #7:#11 // getBoolean:(Ljava/util/Map;)Z
> #14 = Utf8 (Ljava/lang/String;)V
> #15 = Class #1 // java/lang/Object
> {
> ...
> protected void internalTransform(java.lang.String);
> descriptor: (Ljava/lang/String;)V
> flags: ACC_PROTECTED
> Code:
> stack=1, locals=2, args_size=2
> 0: aload_1
> 1: invokestatic #4 // Method
> java/lang/Object.getBoolean:(Ljava/util/Map;)Z
> 4: pop
> 5: return
> }
>
> Case 2: Hotspot may miss some checking for classes with low version
> numbers. I generated two classes for the next Jimple's code: one is with
> version 46, and another with version 51 (they are different only in their
> version numbers). I ran the two classes on Hotspot9, and one (46) was
> accepted and another (51) was rejected (with verifyError). In addition,
For backward compatibility reasons in some/many cases if the verifier
was doing something incorrect, or if the specification was clarified or
modified, then the new rules would only be applied to the latest version
of the classfile (and future versions of course). So you can find a
number of dubious/illegal constructs in say a version 49 class that are
rejected if they appear in say a version 50+ class.
David
> when I ran the two classes on GCJ-Java JVMs, both are rejected with
> VerifyErrors (...verification failed at PC 6 in
> M1433584778S:encodeObject(()V): merging initialized and uninitialized
> types...).
>
> public class M1433584778S extends java.lang.Object
> {
> private void <init>()
> {
> M1433584778S r0;
>
> r0 := @this: M1433584778S;
> specialinvoke r0.<java.lang.Object: void <init>()>();
> return;
> }
>
> public static void encodeObject()
> {
> java.lang.String r1, r2;
> java.lang.Throwable r3;
>
> label0:
> r1 = new java.lang.String;
>
> label1:
> return;
>
> label2:
> r3 := @caughtexception;
> goto label1;
>
> catch java.lang.RuntimeException from label0 to label1 with label2;
>
> }
> }
>
> Decompile the classes and found that:
> public class M1433584778S
> minor version: 0
> major version: 46
> flags: ACC_PUBLIC, ACC_SUPER
> Constant pool:
> #1 = Utf8 ([Ljava/lang/String;)V
> #2 = Utf8 java/lang/Object
> #3 = Utf8 <init>
> #4 = Class #2 // java/lang/Object
> #5 = NameAndType #3:#7 // "<init>":()V
> #6 = Class #14 // java/lang/String
> #7 = Utf8 ()V
> #8 = Utf8 M1433584778S
> #9 = Utf8 Code
> #10 = Utf8 main
> #11 = Utf8 SourceFile
> #12 = Class #8 // M1433584778S
> #13 = Class #15 // java/lang/RuntimeException
> #14 = Utf8 java/lang/String
> #15 = Utf8 java/lang/RuntimeException
> #16 = Utf8 Jasmin
> #17 = Methodref #4.#5 // java/lang/Object."<init>":()V
> #18 = Utf8 encodeObject
> {
> ...
> public static void encodeObject();
> descriptor: ()V
> flags: ACC_PUBLIC, ACC_STATIC
> Code:
> stack=1, locals=1, args_size=0
> 0: new #6 // class java/lang/String
> 3: astore_0
> 4: return
> 5: astore_0
> 6: goto 4
> Exception table:
> from to target type
> 0 4 5 Class java/lang/RuntimeException
> }
>
More information about the hotspot-runtime-dev
mailing list