United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 5104215 Blocked thread status is incorrectly reported as runnable
5104215 : Blocked thread status is incorrectly reported as runnable

Details
Type:
Bug
Submit Date:
2004-09-20
Status:
Resolved
Updated Date:
2005-07-27
Project Name:
JDK
Resolved Date:
2005-07-27
Component:
hotspot
OS:
windows_2000
Sub-Component:
jvmti
CPU:
generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:
6

Related Reports
Backport:

Sub Tasks

Description
/* This test is used to test jdb reporting wrong thread status information
   Steps to reproduce the problem:
     jdb FooTest
     stop at FooTest:53 - the last line in changeVarOne()
     run
     cont    -  a few times
     threads

   All but one of Thread-0 through Thread-9 should be "waiting on a
   monitor". But jdb reports more more than one threads "running". If you do a
   where <thread id> on the running threads, you will see they are actually
   waiting to enter the synchornized method. It seemed like once a thread has 
   been marked as running, jdb will always think it's a running thread even.
*/
public class FooTest
{
    private static int _var;

    public static void main(String[] args) throws Exception
    {
        for( int i = 0; i < 10; i++ )
        {
            final int j = i;
            try
            {
                new Thread(
                    new Runnable()
                    {
                        public void run()
                        {
                            method( j );
                            method( j );
                            method( j );
                        }

                        public void method( int i )
                        {
                            changeVarOne(i);
                        }

                    }
                ).start();
            }
            catch( Exception e ) {}
        }
    }

    public static int _varOne = -1;

    synchronized static public void changeVarOne(int value)
    {
        boolean b = false;
        _varOne = value;
    }
}

                                    

Comments
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
mustang


                                     
2004-09-22
EVALUATION

A thread entering a contended monitor can observe that the monitor owner is NULL. This can happen when another thread is exiting the monitor. When this arises the thread's "threadStatus" isn't set to MONITOR_ENTER even though the thread may block if another thread obtains the monitor. The implication of the bug is that Thread.getState() or JVMTI's GetThreadState may return the thread state as RUNNABLE even though the thread is blocked trying to enter a synchronized block/method. The MonitorContentedEnter event is not impacted this issue.
###@###.### 2004-09-20


###@###.### 2005-07-20 19:05:41 GMT
                                     
2004-09-20
SUGGESTED FIX

Attached webrev.tar contains the final change.
 
We need to replace obj_m->owner() != NULL check with obj_m->contentions() > 0 instead of the following suggested fix.

###@###.### 2005-07-20

------- threadService.hpp -------
*** /tmp/sccs.DHai0s    Mon Sep 20 09:30:00 2004
--- threadService.hpp   Sat Sep 18 16:05:49 2004
***************
*** 372,378 ****
      // enter done for external java world objects and it is contended. All other cases
      // like for vm internal objects and for external objects which are not contended
      // thread status is not changed and contended enter stat is not collected.
!     if (is_alive() && ServiceUtil::visible_oop((oop)obj_m->object()) && obj_m->owner() !=NULL) {
        set_thread_status(java_lang_Thread::BLOCKED_ON_MONITOR_ENTER);
        _stat = java_thread->get_thread_stat();
        _stat->contended_enter();
--- 372,378 ----
      // enter done for external java world objects and it is contended. All other cases
      // like for vm internal objects and for external objects which are not contended
      // thread status is not changed and contended enter stat is not collected.
!     if (is_alive() && ServiceUtil::visible_oop((oop)obj_m->object())) {
        set_thread_status(java_lang_Thread::BLOCKED_ON_MONITOR_ENTER);
        _stat = java_thread->get_thread_stat();
        _stat->contended_enter();

###@###.### 2004-09-20
###@###.### 2005-07-20 19:05:41 GMT
                                     
2004-09-20



Hardware and Software, Engineered to Work Together