JDK-4811870 : Increase reliability of thread startup and shutdown
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 1.4.2,5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2003-02-03
  • Updated: 2008-05-20
  • Resolved: 2003-07-22
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
5.0 tigerFixed
Related Reports
Relates :  
Description
If JNI_AttachCurrentThread finds a pending exception and returns
with JNI_ERR you can hang the VM.

Name: egR10015			Date: 04/21/2003


The following testcases:

nsk/coverage/jni/jni008
nsk/coverage/jni/jni012

have been developed as regression ones for the bug. They will
be available in release r20 of the testbase_nsk located here:

/net/sqesvr.sfbay/export/vsn/VM/testbase/testbase_nsk

The VM hang is observing with Tiger-b04 on all platforms.

Eugene Gorbachev <###@###.###>
======================================================================

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

EVALUATION The minimum fix must be put in. This would be a good time to clean this up for reliability.
11-06-2004

SUGGESTED FIX ###@###.### 03/27/03 Source diffs: src/share/vm/prims/jni.cpp *** 2482,2492 **** HandleMark hm(THREAD); Handle thread_group(THREAD, group); thread->allocate_threadObj(thread_group, thread_name, daemon, THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; ! // FIX THIS: Cleanup is missing return JNI_ERR; } // Enable stack overflow checks thread->create_stack_guard_pages(); --- 2480,2491 ---- HandleMark hm(THREAD); Handle thread_group(THREAD, group); thread->allocate_threadObj(thread_group, thread_name, daemon, THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; ! // Added missing cleanup ! thread->cleanup_failed_attach_current_thread(); return JNI_ERR; } src/share/vm/runtime/thread.cpp *** 1171,1180 **** --- 1171,1182 ---- // Ignore pending exception (ThreadDeath), since we are exiting anyway thread->clear_pending_exception(); } + // For any new cleanup additions, please check to see if they need to be applied to + // cleanup_failed_attach_current_thread as well. void JavaThread::exit(bool destroy_vm) { assert(this == JavaThread::current(), "thread consistency check"); if (!InitializeJavaLangSystem) return; HandleMark hm(this); *** 1320,1329 **** --- 1322,1359 ---- // Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread Threads::remove(this); } + void JavaThread::cleanup_failed_attach_current_thread() { + + if (get_thread_profiler() != NULL) { + get_thread_profiler()->disengage(); + ResourceMark rm; + get_thread_profiler()->print(get_thread_name()); + } + + if (active_handles() != NULL) { + JNIHandleBlock* block = active_handles(); + set_active_handles(NULL); + JNIHandleBlock::release_block(block); + } + + if (free_handle_block() != NULL) { + JNIHandleBlock* block = free_handle_block(); + set_free_handle_block(NULL); + JNIHandleBlock::release_block(block); + } + + if (UseTLAB) { + tlab().reset(); + } + + Threads::remove(this); + this->delete_thread_and_TLS_current(); + } + JavaThread* JavaThread::active() { Thread* thread = ThreadLocalStorage::thread(); assert(thread != NULL, "just checking"); if (thread->is_Java_thread()) { src/share/vm/runtime/thread.hpp *** 683,692 **** --- 683,694 ---- ~JavaThread(); // Cleanup on thread exit void exit(bool destroy_vm); + void cleanup_failed_attach_current_thread(); + // Testers virtual bool is_Java_thread() const { return true; } // compilation void set_is_compiling(bool f) { _is_compiling = f; } putback message: Fixed: Bug 4811870. Synopsis: Increase reliability of thread startup and shutdown Description: If JNI_AttachCurrentThread finds a pending exception and returns with JNI_ERR you can hang the VM. webrev at: http://jse.east.sun.com/~raghuv/webrev/webrev.4811870/ Reviewed by: Karen Kinnear, Jane Loizeaux, Fred Oliver, Paul Hohensee Fix verified (y/n): y Verification testing: Tested using nsk/coverage/jni/jni001 testcase where the main native threads calls AttachCurrentThread(returns no-op for already attached threads) after CreateJavaVM. Also tested using a Multi-threaded application similar to nsk/coverage/jni/jni001 where a new native thread attaches to the JVM created by the main native thread. Please note that none of these tests verify the pending exception scenario in JNI_AttachCurrentThread. (allocate_threadObj fails due to full heap and newly added method cleanup_failed_attach_current_thread() gets executed) However, I tested the fix by forcing the call to the method explicitly in the code. Other testing: 1. jck tests (from /net/testbase-east/src) with arguments: -full, -client, -server. 2. nsk tests with arguments: solaris-sparc client/server rt. 3. SPECJVM98 tests (_213_javac). Details: Ericsson encountered this issue because the GC failed to triger, resulting in a full heap and causing thread->allocate_threadObj to fail in AttachCurrentThread. While Ericsson did investigation and found the root cause for the GC failure, they tested the partial cleanup code for the failed attach_current_thread and it worked for them. Attached are the test programs (invoke12.c and invoke13.c) that I used.
11-06-2004

PUBLIC COMMENTS ###@###.### 03/27/03 Fixed in J2SE 1.5.0 release.
27-03-0003