Two verification missings

Yuting Chen chenyt at cs.sjtu.edu.cn
Thu Jun 25 05:56:31 UTC 2015


Thank you, David. The second example is not simple. In the program the
control/data flows are twisted. I do like the result reported by GCJ-JVM,
as indeed there exist some merging initialized and uninitialized types
(caused by an exception). Also, one possible reason is that the variable r1
is not used. Once r1 is used, all JVMs can report the verifyerrors.

I created the first example because of a mistake: The first parameter
should be of the type java.util.Map but java.lang.String. I can just say
that the type inference/checking mechanism can get further enhanced (but we
can easily decide that the two types are not compatible at the source code
level, or when we compile the programs).

On Wed, Jun 24, 2015 at 9:18 PM, David Holmes <david.holmes at oracle.com>
wrote:

> 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