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

Failure to initialize Jrockit 1.6 using JNI when > 64 TLS slots are allocated

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P3 P3
    • None
    • 6
    • vm-legacy
    • None
    • windows_7

      FULL PRODUCT VERSION :
      java version " 1.6.0_29 "
      Java(TM) SE Runtime Environment (build 1.6.0_29-b11)
      Oracle JRockit(R) (build R28.2.2-7-148152-1.6.0_29-20111221-2103-windows-ia32, compiled mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows 7 Professional
      Microsoft Windows 8 Professional

      A DESCRIPTION OF THE PROBLEM :
      When TlsAlloc() is called successfully for 64 or more times to allocate 64 thread local storage slots and JNI_CreateJavaVM is then used to initialize the jrockit JVM, the initialization fails with the error:
      [ERROR] Could not find allocated thread local data key in TIB.
      [ERROR] Could not create Fast TLD.
      JRockit aborted: Unspecified error (52)

      The reason is because within the jvm.dll, TlsAlloc is first called to allocate a new TLS slot and then subsequently, TLSSetValue is called to set the TLS slot to a value 4711. A pointer is then used to iterate through from the start of the thread environment/information block(TEB/TIB) 4 bytes at a time until 8192 bytes past the start of the TEB/TIB. If it fails to find 4711 within this range of bytes, then the error above occurs. However, because windows only has space in the TEB/TIB for 64 TLS slots, any more slots allocated would be stored in a list pointed to by a pointer in the TEB/TIB called TlsExpansionSlots as stated in:
      http://msdn.microsoft.com/en-us/library/windows/desktop/ms686708%28v=vs.85%29.aspx
      Hence, the logic in the jvm.dll would not be able to find value set in the TLS slot within the TEB/TIB itself unless it follows the TlsExpansionSlots pointer to the list.

      Extensive Details can be found here:
      http://stackoverflow.com/questions/14150746/calling-jni-createjavavm-crashes-the-program


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      In a C program,
      Allocate 64 TLS slots by calling TLSAlloc() 64 times successfully
      Call JNI_CreateJavaVM to initialize the jrockit JVM

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -

      [ERROR] Could not find allocated thread local data key in TIB.
      [ERROR] Could not create Fast TLD.
      JRockit aborted: Unspecified error (52)
      ACTUAL -

      [ERROR] Could not find allocated thread local data key in TIB.
      [ERROR] Could not create Fast TLD.
      JRockit aborted: Unspecified error (52)

      ERROR MESSAGES/STACK TRACES THAT OCCUR :

      [ERROR] Could not find allocated thread local data key in TIB.
      [ERROR] Could not create Fast TLD.
      JRockit aborted: Unspecified error (52)

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      #include <Windows.h>
      #include <tchar.h>
      #include <jni.h>

      HMODULE hModule;
      JavaVM *javaVM = NULL;
      JNIEnv *jniEnv = NULL;

      #define NO_OF_JAVA_VM_OPTIONS 2

      INT _tmain( INT argc, PTSTR argv[] )
      {
      _tprintf(_T( " startJVM Return Status: %d
       " ), startJVM());
      return 0;
      }

      BOOL startJVM()
      {
      JavaVMInitArgs javaVMInitArgs = { 0 };
      JavaVMOption javaVMOption[ NO_OF_JAVA_VM_OPTIONS ] = { 0 };

      BOOL returnStatus = FALSE;

      INT idx = 0;

      TCHAR m_sJVMPath [] = TEXT( " C:\\Program Files (x86)\\Java\\jrockit-jre1.6.0_29-R28.2.2\\bin\\jrockit\\jvm.dll " ); // Edit This To Point To Your jrockit jvm.dll path
      jint ( __stdcall *createJavaVM )( JavaVM **, void **, void * ) = 0;

      _tprintf(_T( " CHECKPOINT 1: After Variable Declaration
       " ));
      _tprintf(TEXT( " JVM Path is %s
       " ),m_sJVMPath);

      // Allocate TLS Slots - Without This JNI_CreateJavaVM Will Work
      for ( idx = 0; idx < 64; ++idx )
      {
      if ( TLS_OUT_OF_INDEXES == TlsAlloc() )
      _tprintf(TEXT( " TLS OUT OF INDEXES
       " ));
      }

      // Load Library
      if ( ( hModule = LoadLibrary( m_sJVMPath ) ) &&
           ( ( createJavaVM ) = ( jint ( __stdcall * )( JavaVM **, void **, void * ) ) GetProcAddress( hModule, " JNI_CreateJavaVM " ) ) )
      {
      _tprintf(_T( " CHECKPOINT 2: After Loading JVM.dll
       " ));

      // Initialize Argument
      memset( &javaVMInitArgs, 0, sizeof( javaVMInitArgs ) );
               
      _tprintf(_T( " CHECKPOINT 3: After Setting javaVMInitArgs To 0
       " ));

      // Set Version
      javaVMInitArgs.version = JNI_VERSION_1_6;

      // Set Option
      javaVMOption[0].optionString = " -Xms64m " ;
      javaVMOption[1].optionString = " -Xmx64m " ;

      javaVMInitArgs.nOptions = NO_OF_JAVA_VM_OPTIONS;
      javaVMInitArgs.options = javaVMOption;
      javaVMInitArgs.ignoreUnrecognized = JNI_FALSE;

      _tprintf(_T( " CHECKPOINT 4: After Initializing javaVMInitArgs
       " ));

      // Create JVM
      returnStatus = ( ( *createJavaVM )( &javaVM, ( void ** )&jniEnv, &javaVMInitArgs ) >= 0 ? TRUE : FALSE );
           
      _tprintf(_T( " CHECKPOINT 5: After Creating Java VM - %d
       " ), returnStatus);

      // Create Object / MethodID References
      if ( returnStatus )
      {
      // Destroy JVM
      if ( javaVM )
      ( *javaVM ) -> DestroyJavaVM( javaVM );
      }
      // Free Library
      FreeLibrary( hModule );
      }

      return returnStatus;
      }
      ---------- END SOURCE ----------

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: