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

regression: java_suspend_self() has race with external suspend

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 1.4.2
    • 1.4.2
    • vm-legacy
    • mantis
    • sparc
    • solaris_8

      ###@###.### 2002-11-11

      JavaThread::java_suspend_self() has a race with a subsequent external
      suspend request. I believe this race has been lying dormant in the code
      since we implemented the self-suspend logic (in Ladybird?). Mantis-B05
      contains a fix for the following bug:

      4683006 3/3 3rd party memory managers risk deadlock with JVMDI/JVMPI/JVM_Suspend

      This fix stops using forced suspension with native threads which is the
      right thing to do. However, there is an unfortunate side effect of
      exposing this race. The fix for 4683006 is _not_ broken! It merely
      exposes a race condition. The condition appears to be pretty rare. I've
      only seen it on my Ultra-80 2x450MHZ machine running Solaris 8 with the
      java_g PepTest stress test. It has not been seen on any other stress
      test config nor on any other OS platform.

      sampler target
      ============================ ===========================================
      SuspendThreadList() :
        enter(SR_lock) :
        set_external_suspend() :
        exit(SR_lock) :
        : post_event()
        : ThreadToNativeFromVM
        : handle_special_runtime_exit_condition()
        : if (is_external_suspend_with_lock() {
        : StateSaver sv
        : java_suspend_self() {
        : enter(SR_lock)
        : set_self_suspended()
        : while (is_self_suspended())
        : SR_lock.wait()
        java_suspend(target) :
          VM_ThreadSuspend :
        VM_ForceSafepoint :
                                                :
      GetCallTrace() :
        wait_for_ext_suspend...() :
        fill_call_trace() :
                                                :
      ResumeThreadList() :
        enter(SR_lock) :
        clear_external_suspend() :
        if (is_self_suspended()) { :
          clear_self_suspended(); :
          SR_lock->notify_all(); : notify received but
        } : thread doesn't run
                                                :
      SuspendThreadList() :
        enter(SR_lock) :
        set_external_suspend() :
        exit(SR_lock) :
        java_suspend(target) :
          VM_ThreadSuspend :
        VM_ForceSafepoint :
                                                :
      GetCallTrace() :
        wait_for_ext_suspend...() :
        fill_call_trace() : thread runs finally
        : : reenter SR_lock
        : : sees no longer self suspended
        : exit(SR_lock)
        : } // end java_suspend_self()
        : sampler thread crashes // StateSaver destructor called here
        : at this point // which whacks the _post_Java_state
        : // field while sampler is walking
        : } // end if (is_external_suspend...()
        : } // end handle_special_....()
        :
        : <hprof-code>
        : raw_monitor_enter()
        : enter(SR_lock)
        : while (is_external_suspend())
        : exit(SR_lock)
        : {
        : StateSaver sv
        : // this StateSaver makes the thread
        : // look okay
        : java_suspend_self() {
        : enter(SR_lock)
        : set_self_suspended()
        : while (is_self_suspended())
        : SR_lock.wait()
        : // we find target thread here

            dcubed Daniel Daugherty
            dcubed Daniel Daugherty
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: