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

Array accesses using sun.misc.Unsafe cause data corruption or SIGSEGV

    XMLWordPrintable

Details

    • x86_64
    • linux

    Description

      FULL PRODUCT VERSION :
      java version "1.8.0_45"
      Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
      Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

      Also on:
      1.8.0_60-ea-b18
      1.9.0-ea-b67

      FULL OS VERSION :
      3.10.0-229.4.2.el7.x86_64 Centos 7
      3.13.0-44-generic Ubuntu 14
      OSX 10.10.3 (14.3.0 Darwin)


      A DESCRIPTION OF THE PROBLEM :
      I'm trying to use a continuous native memory region allocated by sun.misc.Unsafe.allocateMempory() as a large long array.

      When this memory region is modified with Unsafe.putLong() and then accessed by Unsafe.getLong() in a long loop, either getLong() reads an incorrect value (which is not the one written by putLong()) or process crashes with a SIGSEGV.

      This is most probably Unsafe.getLong() reads a wrong memory address and when that address is an invalid one, process crashes.

      It seems this is already reported by https://bugs.openjdk.java.net/browse/JDK-8076445 but closed as "Cannot Reproduce".

      THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: No

      THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes

      REGRESSION. Last worked in version 8u31

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      - Allocate a large memory region with sun.misc.Unsafe.allocateMempory()
      - In a loop, starting from the beginning of the region to the end:
          * write a long value to the current address using Unsafe.putLong(address, value)
          * read long value from current address using readValue = Unsafe.getLong(address)
          * compare the readValue with the initial value

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      Expected result is, process should not crash and read value should be equal to written value.

      Actual result is, either getLong() reads an incorrect value (which is not the one written by putLong()) or process crashes with a SIGSEGV.
      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Exception in thread "main" java.lang.AssertionError: Expected: 546624, Actual: 0
      at Test.main(Test.java:26)

      ---- OR -----

      #
      # A fatal error has been detected by the Java Runtime Environment:
      #
      # SIGSEGV (0xb) at pc=0x00000001029965d5, pid=46768, tid=4867
      #
      # JRE version: Java(TM) SE Runtime Environment (8.0_45-b14) (build 1.8.0_45-b14)
      # Java VM: Java HotSpot(TM) 64-Bit Server VM (25.45-b02 mixed mode bsd-amd64 compressed oops)
      # Problematic frame:
      # J 67% C1 Test.main([Ljava/lang/String;)V (136 bytes) @ 0x00000001029965d5 [0x0000000102996000+0x5d5]
      #
      # Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
      #
      # If you would like to submit a bug report, please visit:
      # http://bugreport.java.com/bugreport/crash.jsp
      #

      --------------- T H R E A D ---------------

      Current thread (0x00007f9b29007000): JavaThread "main" [_thread_in_Java, id=4867, stack(0x000000010276a000,0x000000010286a000)]

      siginfo: si_signo: 11 (SIGSEGV), si_code: 1 (SEGV_MAPERR), si_addr: 0x000000011bdbc580

      Registers:
      RAX=0x000000011ba238b0, RBX=0x00000000000186a0, RCX=0x0000000000000158, RDX=0x0000000000000008
      RSP=0x0000000102869840, RBP=0x00000001028699b0, RSI=0x0000000000010716, RDI=0x00000007955937b0
      R8 =0x00000000000838b0, R9 =0x000000011b9a0000, R10=0x0000000000000020, R11=0x00007f9b28500000
      R12=0x0000000000000000, R13=0x0000000102995d50, R14=0x0000000102869948, R15=0x00007f9b29007000
      RIP=0x00000001029965d5, EFLAGS=0x0000000000010202, ERR=0x0000000000000004
        TRAPNO=0x000000000000000e

      Top of Stack: (sp=0x0000000102869840)
      0x0000000102869840: 00000001028698c8 0000000102869888
      0x0000000102869850: 00000000000000df 0000000000000000
      0x0000000102869860: 0000000102869948 00007f9b29007000
      0x0000000102869870: 00000001028698c8 000000010288aada
      0x0000000102869880: 000000010288aa98 0000000102869888
      0x0000000102869890: 0000000102995d50 0000000102869948
      0x00000001028698a0: 00000001172f07d0 0000000000000000
      0x00000001028698b0: 00000001172f0660 0000000000000000
      0x00000001028698c0: 0000000102869948 00000001028699b0
      0x00000001028698d0: 000186a000010716 000000011b9a0000
      0x00000001028698e0: 00000007955937b0 0000000000000000
      0x00000001028698f0: 0000000000010715 0000000000000000
      0x0000000102869900: 000000011ba238a8 0000000000000000
      0x0000000102869910: 0000000000010716 000000011b9a0000
      0x0000000102869920: 0000000000000000 00000000000c3500
      0x0000000102869930: 00000001028699b0 000000010286c7a7
      0x0000000102869940: 00000007955937b0 0000000795675c80
      0x0000000102869950: 0000000100001fa0 000000000000000a
      0x0000000102869960: 00007f9b29007000 0000000000000001
      0x0000000102869970: 000000010286c71f 00000001172f0660
      0x0000000102869980: 0000000102869a48 0000000102869dd0
      0x0000000102869990: 000000010000000a 00000001172f0660
      0x00000001028699a0: 000000010287cc00 0000000102869b88
      0x00000001028699b0: 0000000102869b60 0000000101ae032a
      0x00000001028699c0: a000000000000001 00007f9b29007000
      0x00000001028699d0: a000000000000000 0000000102869dd0
      0x00000001028699e0: 0000000000000000 000000010287cc00
      0x00000001028699f0: 0000000000000000 0000000102869b80
      0x0000000102869a00: 0000000102869dc8 00007f9b29007000
      0x0000000102869a10: 00007f9b29007000 00007f9b28505930
      0x0000000102869a20: 00007f9b28505d60 00007f9b28505d70
      0x0000000102869a30: 00007f9b28505e48 00000000000000d8

      Instructions: (pc=0x00000001029965d5)
      0x00000001029965b5: 08 00 00 00 00 00 00 00 4c 8b c8 49 8b c0 48 0f
      0x00000001029965c5: af c2 49 03 c1 48 3b 07 49 c1 e0 03 4f 89 04 01
      0x00000001029965d5: 4f 8b 1c c1 49 8b d0 49 3b d3 48 ba 60 13 2f 17
      0x00000001029965e5: 01 00 00 00 48 b8 d8 01 00 00 00 00 00 00 0f 85

      Register to memory mapping:

      RAX=0x000000011ba238b0 is an unknown value
      RBX=0x00000000000186a0 is an unknown value
      RCX=0x0000000000000158 is an unknown value
      RDX=0x0000000000000008 is an unknown value
      RSP=0x0000000102869840 is pointing into the stack for thread: 0x00007f9b29007000
      RBP=0x00000001028699b0 is pointing into the stack for thread: 0x00007f9b29007000
      RSI=0x0000000000010716 is an unknown value
      RDI=0x00000007955937b0 is an oop
      sun.misc.Unsafe
       - klass: 'sun/misc/Unsafe'
      R8 =0x00000000000838b0 is an unknown value
      R9 =0x000000011b9a0000 is an unknown value
      R10=0x0000000000000020 is an unknown value
      R11=0x00007f9b28500000 is an unknown value
      R12=0x0000000000000000 is an unknown value
      R13=0x0000000102995d50 is at entry_point+-688 in (nmethod*)0x0000000102995d50
      R14=0x0000000102869948 is pointing into the stack for thread: 0x00007f9b29007000
      R15=0x00007f9b29007000 is a thread


      Stack: [0x000000010276a000,0x000000010286a000], sp=0x0000000102869840, free space=1022k
      Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
      J 67% C1 Test.main([Ljava/lang/String;)V (136 bytes) @ 0x00000001029965d5 [0x0000000102996000+0x5d5]
      v ~StubRoutines::call_stub
      V [libjvm.dylib+0x2e032a] JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+0x6ae
      V [libjvm.dylib+0x316a36] jni_invoke_static(JNIEnv_*, JavaValue*, _jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, Thread*)+0x1bf
      V [libjvm.dylib+0x30f7b0] jni_CallStaticVoidMethod+0x15d
      C [java+0x39ae] JavaMain+0x9b1
      C [libsystem_pthread.dylib+0x3268] _pthread_body+0x83
      C [libsystem_pthread.dylib+0x31e5] _pthread_body+0x0
      C [libsystem_pthread.dylib+0x141d] thread_start+0xd
      C 0x0000000000000000


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import sun.misc.Unsafe;

      import java.lang.reflect.Field;

      public class Test {

          public static void main(String[] args) throws Exception {
              Unsafe unsafe = findUnsafe();
              // 10000 pass
              // 100000 jvm crash
              // 1000000 fail
              int count = 100000;
              long size = count * 8L;
              long baseAddress = unsafe.allocateMemory(size);

              try {
                  for (int i = 0; i < count; i++) {
                      long address = baseAddress + (i * 8L);

                      long expected = i;
                      unsafe.putLong(address, expected);

                      long actual = unsafe.getLong(address);

                      if (expected != actual) {
                          throw new AssertionError("Expected: " + expected + ", Actual: " + actual);
                      }
                  }
              } finally {
                  unsafe.freeMemory(baseAddress);
              }
          }

          private static Unsafe findUnsafe() {
              try {
                  Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
                  theUnsafe.setAccessible(true);
                  Unsafe unsafe = (Unsafe) theUnsafe.get(null);
                  return unsafe;
              } catch (Exception e) {
                  throw new RuntimeException(e);
              }
          }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Downgrade to 1.8.0.31 or 1.7.

      Also converting index multiplier to integer instead of long also works.

      for (int i = 0; i < count; i++) {
          long address = baseAddress + (i * 8); // <--- here, integer 8 instead of long 8

          long expected = i;
          unsafe.putLong(address, expected);

          long actual = unsafe.getLong(address);

          if (expected != actual) {
              throw new AssertionError("Expected: " + expected + ", Actual: " + actual);
          }
      }

      Attachments

        Issue Links

          Activity

            People

              roland Roland Westrelin
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: