JDK-4873131 : JVM hangs up with C++ std lib because of mutex deadlock in 1.3.1_03/1.4.0_0X
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 1.3.1_03,1.3.1_09
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: solaris_8,windows_2000
  • CPU: x86,sparc
  • Submitted: 2003-06-03
  • Updated: 2003-10-15
  • Resolved: 2003-09-15
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.3.1_10 10Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
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 ============================================



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

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: 1.3.1_10 FIXED IN: 1.3.1_10 INTEGRATED IN: 1.3.1_10 VERIFIED IN: 1.3.1_10
14-06-2004

EVALUATION Yes, it's the same problem that I fixed under bugid 4526887. Details are at http://raq.sfbay/~huanghui/webrev/20020208. thanks, -hui Please see above putback for fix to this issue. ###@###.### 2003-06-04
04-06-2003