Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8146285

aarch32: NegativeArraySizeException not thrown correctly

XMLWordPrintable

    • inapplicable
    • aarch32
    • linux

      the test following case should throw an NegativeArraySizeException
      as JVM spec requires for the array size being -1, but right now, jvm
      crashes when it runs the case:
      ///////////////// Test.java /////////////////////
      public class Test {
        public static void main(String[] args)
        {
          try { (new byte[-1])[0] = 0; }
          catch (Exception e) { System.out.println(e); }
        }
      }
      ///////////////// Test.java end /////////////////////

      and its bytecodes:
      ////////////////////////////////////////////////////
        public static void main(java.lang.String[]);
          descriptor: ([Ljava/lang/String;)V
          flags: ACC_PUBLIC, ACC_STATIC
          Code:
            stack=3, locals=2, args_size=1
               0: iconst_m1
               1: newarray byte
               3: iconst_0
               4: iconst_0
               5: bastore
               6: goto 17
               9: astore_1
              10: getstatic #3 // Field
      java/lang/System.out:Ljava/io/PrintStream;
              13: aload_1
              14: invokevirtual #4 // Method
      java/io/PrintStream.println:(Ljava/lang/Object;)V
              17: return
            Exception table:
               from to target type
                  0 6 9 Class java/lang/Exception
      //////////////////// end ////////////////////////

      Analysis:
      when interpreting the "newarray" bytecode, JVM calls
      InterpreterRuntime::newarray() via call_VM template to allocate a byte
      array and push a NegativeArraySizeException object at the top of stack for
      array size being -1. And then at the end of call_VM template, JVM checks if
      there is any pending exception to be handled. It calls
      SharedRuntime::exception_handler_for_return_address() to determine the
      proper handler. Current implementation leads to JVM crash because it finds
      the handler in call stub frame, and passes the JVM control flow to
      StubRoutines::catch_exception_entry().

      It seems JVM should find the exception handler in the Java frame, and pass
      as argument the real call site to
      SharedRuntime::exception_handler_for_return_address(). Current
      implementation uses lr register to hold the call site for
      SharedRuntime::exception_handler_for_return_address(). I believe lr
      register is assigned an improper value so I suppose the attached patch to
      fix this bug:

      //////////////////// patch ////////////////////////
      diff -r f69a4ff3f0bb src/cpu/aarch32/vm/macroAssembler_aarch32.cpp
      --- a/src/cpu/aarch32/vm/macroAssembler_aarch32.cpp Wed Dec 23 12:21:32
      2015 +0000
      +++ b/src/cpu/aarch32/vm/macroAssembler_aarch32.cpp Tue Dec 29 20:12:55
      2015 +0800
      @@ -591,7 +591,7 @@
           ldr(rscratch2, Address(java_thread,
      in_bytes(Thread::pending_exception_offset())));
           Label ok;
           cbz(rscratch2, ok);
      - ldr(lr, Address(rfp, frame::return_addr_offset));
      + mov(lr, target(l));
           lea(rscratch2,
      RuntimeAddress(StubRoutines::forward_exception_entry()));
           b(rscratch2);
           bind(ok);
      //////////////////// end ////////////////////////

            enevill Ed Nevill
            enevill Ed Nevill
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: