JDK-4763264 : JDI spec: ObjectReference.waitingThreads: add the owner must be suspended
  • Type: Bug
  • Component: core-svc
  • Sub-Component: debugger
  • Affected Version: 1.4.2,5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS: generic,solaris_9
  • CPU: generic,sparc
  • Submitted: 2002-10-15
  • Updated: 2023-12-14
  • Resolved: 2016-11-03
Related Reports
Relates :  
Description
###@###.### 2002-10-15

While working on the fix for the following bug:

    4546581 4/5 GetCurrentContendedMonitor, GetOwnedMonitorInfo,
                GetMonitorInfo not implemented

I ran into a minor bug in the following test:

    nsk/jdi/VirtualMachine/canGetMonitorInfo/cangetmonitorinfo001

The main thread in the debuggee starts a worker thread while holding
a monitor, lockingObject. The worker thread blocks on the monitor
and the debuggee main thread waits for the debugger to tell it to
proceed.

The debugger suspends the worker thread while it is waiting to enter
the monitor and verifies the JVM/DI GetCurrentContendedMonitor()
call. It also verifies the JVM/DI GetMonitorInfo() call indirectly
via the JDI ObjectReference.waitingThreads() call.

The GetMonitorInfo() call fails because the debuggee main thread is
not suspended (JVMDI_ERROR_THREAD_NOT_SUSPENDED). Here is the
relevant requirements from the JVM/DI spec:

    Get Monitor Info
    :
    Get information about the the object's monitor The fields of the
    JVMDI_owned_monitor_info structure are filled in with details of
    the monitor. Each thread that might affect the monitor state must
    either be suspended or must be the current thread. 

The debuggee main thread owns the monitor and is not the caller of
GetMonitorInfo() so it must be suspended.

The JDI spec for ObjectReference.waitingThreads() does not document
the requirement that the owner of the monitor needs to be suspended
(or the current thread). This is because there is no 1-1 mapping
between the JDI APIs and the JVM/DI APIs. The waitingThreads() API
doesn't care about the owning thread. In other words, the
waitingThreads() API doesn't know that it is built on top of the
JVM/DI GetMonitorInfo() API so it doesn't describe requirements
for the underlying API that do not directly map to the information
that it is trying to return (a list of waiting threads).

It is entirely possible that the ObjectReference.waitingThreads()
API should be suspending the thread that owns the object on behalf
of the caller. However, I can't make that call.

Comments
This is not on our list of current priorities, if this changes please re-open this issue.
03-11-2016

SUGGESTED FIX ###@###.### 2002-10-15 Here are the context diffs for the suggested fix for the test: *** cangetmonitorinfo001.java.orig Thu Aug 15 21:38:59 2002 --- cangetmonitorinfo001.java Tue Oct 15 11:33:54 2002 *************** *** 110,115 **** --- 110,116 ---- static VirtualMachine vm = null; ReferenceType testedclass = null; + ThreadReference mainThread = null; ThreadReference thread2 = null; *************** *** 203,211 **** listIterator = allThreads.listIterator(); for (;;) { try { ! thread2 = (ThreadReference) listIterator.next(); ! if (thread2.name().equals(threadName)) ! break ; } catch ( NoSuchElementException e ) { log3("ERROR: NoSuchElementException for listIterator.next()"); log3("ERROR: NO 'main' thread ?????????!!!!!!!"); --- 204,219 ---- listIterator = allThreads.listIterator(); for (;;) { try { ! ThreadReference t = (ThreadReference) listIterator.next(); ! if (mainThread == null && t.name().equals("main")) { ! mainThread = t; ! } ! if (thread2 == null && t.name().equals(threadName)) { ! thread2 = t; ! } ! if (mainThread != null && thread2 != null) { ! break; ! } } catch ( NoSuchElementException e ) { log3("ERROR: NoSuchElementException for listIterator.next()"); log3("ERROR: NO 'main' thread ?????????!!!!!!!"); *************** *** 242,247 **** --- 250,259 ---- if (expresult != returnCode0) break label1; + // JVM/DI GetMonitorInfo() requires the caller to be the + // current thread or to be suspended. + log2(" suspending the main thread"); + mainThread.suspend(); if (vm.canGetMonitorInfo()) { log2(".......vm.canGetMonitorInfo() == true"); *************** *** 273,278 **** --- 285,293 ---- } + log2(" resuming the main thread (for case it was suspended)"); + mainThread.resume(); + log2(" resuming the thread2 (for case it was suspended)"); thread2.resume();
11-06-2004

EVALUATION The Synopsis used to be: nsk/jdi/VirtualMachine/canGetMonitorInfo/cangetmonitorinfo001 is missing a suspend Name: dkR10014 Date: 11/05/2002 Dostar Kasymov, ###@###.###, 11/04/2002 The jdk1.4.2 JDI spec for ObjectReference.waitingThreads() requires only waiting threads need to be suspended: waitingThreads ... Throws: UnsupportedOperationException - if the target VM does not support this operation. IncompatibleThreadStateException - if any waiting thread is not suspended in the target VM Thus the test conforms to the spec. I believe either the spec should be corrected to require the owner thread to be suspended, or an implementation of the method should implicitly suspend the owner thread during a call. I reassign the bug to java/debugger category for further evaluation. ====================================================================== I believe that it is best to change the spec to say that both the owning thread and the waiting threads must be suspended . This is consistent with ObjectReference.owningThread(). ###@###.### 2003-01-14
14-01-2003