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

JVM hangs up with C++ std lib because of mutex deadlock in 1.3.1_03/1.4.0_0X

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P3
    • Resolution: Fixed
    • Affects Version/s: 1.3.1_03, 1.3.1_09
    • Fix Version/s: 1.3.1_10
    • Component/s: hotspot
    • Labels:
    • Subcomponent:
    • Resolved In Build:
      10
    • CPU:
      x86, sparc
    • OS:
      solaris_8, windows_2000
    • Verification:
      Verified

      Description

      A licensee faces with hang up when their application program terminates.
      (the application uses JNI)

      CONFIGRATION:
        OS: Solaris8
        JRE: 1.3.1_03/1.4.0

      REPRODUCE:
        1) Compile the attached code(the attached file includes java program
           and c program)
        2) Invoke java class (invoke the command "java b")

        NOTE:
         The attached file includes the files in the following structure
         and 2 reproducible case.

       - b.java (JNI invoker)
         + case1
           + d.cpp JNI code, this emulates malloc().
           + p7839 pstack data at hang up
         + case2
           + e.cpp JNI code (malloc()/ free())
           + p7910 pstack at hang up


      INVESTIGATION:

       They consider it caused from the dead lock in malloc_lock mutex.

       When the program includes C++ Standard library, destructor runs after
       exit().

       for example,

        //------------------------------------
        #include <iostream>
          ...
         std::cout << "using std ::cout\n";
          ...
        //------------------------------------

        The above code runs as the following stack sequence on exitting.

      === Stack trace ===
       ff30b148 _mutex_adaptive_lock (ff3398e4, 4c00, 1000, fffeffff, 1, 4d58) + 160
       ff30ae80 _cmutex_lock (ff2c05f0, ff32e000, ff3e60c8, ff242ac4, 2cafc, ff3c6700) + 70
       ff242ac4 free (0, 5f, ff3a072c, ff3e66c0, 0, 1) + 18
       ff1d3700 void operator delete(void*) (0, 0, 0, ff350a24, 16000, 0) + 4
       ff350a24 std::ios_base::~ios_base #Nvariant 1() (ff37e140, ff37e150, ff37e140, 0, 1d0, ff37e51c) + 8c
       ff351464 void __STATIC_DESTRUCTOR() (ff37d534, 178d8, 0, ff32e000, 2cb4c, 0) + 48
       ff367368 _fini (0, fee0bd70, ff3e60c8, f, 2cafc, ff3bc8ec) + 4
       ff3bc8f4 call_fini (ff3e6178, ff3e6158, ff3e66c0, 40000, ff0214d8, ff3a072c) + f0
       ff3bca84 atexit_fini (ff3e60c8, ff3e66c0, ff3a024c, ff3e60c8, fe73c000, 0) + 6c
       ff21bc54 _exithandle (ff2c20bc, ff2be5f0, ff2c20d8, 5, e03fcc64, ff2bc000) + 74
       ff29f768 exit (3, fe73c000, ffbee254, fee0b, fe73c000, fee0bac4) + 24
      ==================

      JVM suppends all the JavaThreads. However, if a thread is executing
      malloc(), the very thread will be suspended without releasing mutex lock.
      As the result, std::ios_base::~ios_base -> delete -> free keeps waiting
      for the mutex lock release.


      Also they consider the below part related to this issue.


      =====1.4.0 Start ============================================
        void doit() {
          // make doubly sure that a thread doesn't wake up at an inconvenient time
          // Note: this is necessary or the threads continue to run
          NOT_CORE(CompileBroker::wait_for_compile_threads_to_block());

          assert(Threads_lock->owner() == Thread::current(), "must have threads lock");
          for (JavaThread *thr = Threads::first(); thr != NULL; thr = thr->next()) {
            thr->shutdown_suspend();
          }

          // Check for exit hook
          exit_hook_t exit_hook = Arguments::exit_hook();
          if (exit_hook != NULL) {
            exit_hook(_code);
          } else {
            ::exit(_code);
          }
        }
      =====1.4.0 End ============================================

      =====1.4.1 Start ============================================
      void VM_Exit::doit() {
        // Stop compiler threads
        NOT_CORE(CompileBroker::wait_for_compile_threads_to_block());

        if (_exit_vm) {
          // Wait for a short period for threads in native to block. Any thread
          // still executing native code after the wait will be stopped at
          // native==>Java/VM barriers.
          // Among 16276 JCK tests, 94% of them come here without any threads still
          // running in native; the other 6% are quiescent within 250ms (Ultra 80).
          wait_for_threads_in_native_to_block(300);

          set_vm_exited();

          // cleanup globals resources before exiting. exit_globals() currently
          // cleans up outputStream resources and PerfMemory resources.
          exit_globals();

          // Check for exit hook
          exit_hook_t exit_hook = Arguments::exit_hook();
          if (exit_hook != NULL) {
            exit_hook(_exit_code);
          } else {
            ::exit(_exit_code);
          }
        }
      }
      =====1.4.1 End ============================================



      ==============================================================================

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                duke J. Duke (Inactive)
                Reporter:
                tbaba Tadayuki Baba (Inactive)
              • Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: