JDK-4881230 : jdbx JNIEnv proxy workaround needs to be retired
  • Type: Bug
  • Component: vm-legacy
  • Sub-Component: jvmdi
  • Affected Version: 6
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic,solaris_9
  • CPU: generic
  • Submitted: 2003-06-19
  • Updated: 2019-03-21
  • Resolved: 2004-08-30
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.
JDK 6
6 mustangFixed
Related Reports
Relates :  
Description
###@###.### 2003-06-19

Older versions of jdbx used to have a debugger agent thread that operated
on behalf of another thread. However, that only works using the product
VM. The debug VM has assertions that fail when this type of behavior is
tried. A work around was put in place in the Ladybird (1.3.1) release
that allowed the product mode bits to continue working:

4432884 1/2 jdbx does not work with jdk 1.3.1 starting with rc1 build
            19 onwards

I broke the workaround in Hopper-B06 with some of my suspend/resume
changes. The work around was restored with the following bug fix:

4657650 3/5 threadstart002: suspend/resume fails with intermediate
            DeleteGlobalRef call

The old behavior of jdbx is wrong as shown by the following docs:

> From: Jim Holmlund <###@###.###>
> Date: Fri, 12 Apr 2002 18:52:03 -0700 (PDT)
> Subject: Re: need opinion on 4657650
>
> It seems to also be the opinion of the JNI spec; see the last sentence
> of section 11.5.1 here
>    http://java.sun.com/docs/books/jni/html/design.html#8371
> 
> and section 8.1.1 here:
>    http://java.sun.com/docs/books/jni/html/other.html#29362

These two sections explicitly rule out making a JNI call with another
thread's JNIEnv.

We have carried around the workaround for many releases and it
continues to cause confusion. We even have an NSK test that verifies
that the workaround is still in place:

    nsk/jvmdi/events/threadstart002

The purpose of this bug report is to track the process of removing the
workaround from the VM. Once this is done, threadstart002 will fail
in both product mode and debug mode.

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: mustang FIXED IN: mustang INTEGRATED IN: mustang
31-08-2004

EVALUATION Name: dd4877 Date: 07/21/2004 daniel.daugherty@Sun 2004-07-21 This fix can be done in stages: stage 1) change the jdbx workaround to only be enabled with a specific command line flag (-XX:+AllowJNIEnvProxy) stage 2) get bits to the jdbx group for validation (without using the flag) stage 3) once the jdbx group approves the change, then the code controlled by the new flag may be removed This bug covers stage 1 of the process. ======================================================================
31-08-2004

SUGGESTED FIX Name: dd4877 Date: 07/21/2004 daniel.daugherty@Sun 2004-07-21 Here are the context diffs for the proposed fix: ------- src/share/vm/runtime/globals.hpp ------- *** /tmp/sccs.y4aiee Wed Jul 21 15:36:52 2004 --- globals.hpp Wed Jul 21 15:34:15 2004 *************** *** 691,696 **** --- 691,699 ---- product(bool, PostSpinYield, true, "Yield after inner spinning loop") + product(bool, AllowJNIEnvProxy, false, + "Allow JNIEnv proxies for jdbx") + product(bool, CheckJNICalls, false, "Verify all arguments to JNI calls") ------- src/share/vm/runtime/thread.cpp ------- *** /tmp/sccs.miaaFf Wed Jul 21 15:37:50 2004 --- thread.cpp Wed Jul 21 15:37:31 2004 *************** *** 1684,1695 **** void JavaThread::handle_special_runtime_exit_condition(bool check_asyncs) { // // Check for pending external suspend. Internal suspend requests do ! // not use handle_special_runtime_exit_condition(). Also, don't ! // self-suspend if the target thread is not current thread. jdbx threads ! // call into the VM with another thread's JNIEnv so we can be here ! // operating on behalf of a suspended thread (4432884). bool do_self_suspend = is_external_suspend_with_lock(); ! if (do_self_suspend && this == JavaThread::current()) { // // Because thread is external suspended the safepoint code will count // thread as at a safepoint. This can be odd because we can be here --- 1684,1696 ---- void JavaThread::handle_special_runtime_exit_condition(bool check_asyncs) { // // Check for pending external suspend. Internal suspend requests do ! // not use handle_special_runtime_exit_condition(). ! // If JNIEnv proxies are allowed, don't self-suspend if the target ! // thread is not the current thread. In older versions of jdbx, jdbx ! // threads could call into the VM with another thread's JNIEnv so we ! // can be here operating on behalf of a suspended thread (4432884). bool do_self_suspend = is_external_suspend_with_lock(); ! if (do_self_suspend && (!AllowJNIEnvProxy || this == JavaThread::current())) { // // Because thread is external suspended the safepoint code will count // thread as at a safepoint. This can be odd because we can be here *************** *** 1912,1921 **** assert(!curJT->has_last_Java_frame() || curJT->frame_anchor()->walkable(), "Unwalkable stack in native->vm transition"); ! // Don't self-suspend if the caller is not the target thread. jdbx ! // threads can call into the VM with another thread's JNIEnv so we // can be here operating on behalf of a suspended thread (4432884). ! if (do_self_suspend && curJT == thread) { JavaThreadState state = thread->thread_state(); // We mark this thread_blocked state as a suspend-equivalent so --- 1913,1923 ---- assert(!curJT->has_last_Java_frame() || curJT->frame_anchor()->walkable(), "Unwalkable stack in native->vm transition"); ! // If JNIEnv proxies are allowed, don't self-suspend if the target ! // thread is not the current thread. In older versions of jdbx, jdbx ! // threads could call into the VM with another thread's JNIEnv so we // can be here operating on behalf of a suspended thread (4432884). ! if (do_self_suspend && (!AllowJNIEnvProxy || curJT == thread)) { JavaThreadState state = thread->thread_state(); // We mark this thread_blocked state as a suspend-equivalent so ======================================================================
31-08-2004