-
Bug
-
Resolution: Fixed
-
P3
-
1.4.2
-
beta
-
x86
-
linux_redhat_7.2
###@###.### 2002-11-14
Linux stress testing on 2002.11.11 shows a 5% MultiThreadedBreakpoints
test failure with the following assertion:
# assert(jt->has_last_Java_frame(), "must have last Java frame")
#
# Error happened during: thread suspend
#
# Error ID: src/os/linux/vm/os_linux.cpp, 1885
PepTest shows a 2-3% failure rate with the same assertion. There were
also some hangs.
I did some poking around and found a race that explains the assertion
failures. I have not gotten a stack track from the hang yet, but its
frequency is very low.
jni_DestroyJavaVM() creates a new JavaThread via
JavaVM::AttachCurrentThread(). This is implemented by
jni_AttachCurrentThread() which adds the thread to the threads list
before creating the Java level thread object via a call to
JavaThread::allocate_threadObj().
Once the thread is on the threads list, it is possible for the JVM/DI
GetAllThreads() API to see it. Thus, the JPDA backend will have a
chance to externally suspend the thread before its THREAD_START event.
In the case of this thread, it self-suspends in
JavaCallWrapper::JavaCallWrapper() just after changing its
ThreadState from _thread_in_vm to _thread_in_Java. It has not yet
run any Java code so _last_Java_sp is NULL.
The VMThread starts a safepoint at the same time that the thread is
trying to self-suspend. If the VMThread makes it past its
is_any_suspended_with_lock() check, it will:
- vm_suspend() the thread
- find the thread in state _thread_in_Java
- call get_top_frame()
- call fetch_top_frame()
- fail an assertion because _last_Java_sp is NULL
The assertion is new with the Itanium merge which is why I didn't see
this problem with my early Mantis stress runs.
Linux stress testing on 2002.11.11 shows a 5% MultiThreadedBreakpoints
test failure with the following assertion:
# assert(jt->has_last_Java_frame(), "must have last Java frame")
#
# Error happened during: thread suspend
#
# Error ID: src/os/linux/vm/os_linux.cpp, 1885
PepTest shows a 2-3% failure rate with the same assertion. There were
also some hangs.
I did some poking around and found a race that explains the assertion
failures. I have not gotten a stack track from the hang yet, but its
frequency is very low.
jni_DestroyJavaVM() creates a new JavaThread via
JavaVM::AttachCurrentThread(). This is implemented by
jni_AttachCurrentThread() which adds the thread to the threads list
before creating the Java level thread object via a call to
JavaThread::allocate_threadObj().
Once the thread is on the threads list, it is possible for the JVM/DI
GetAllThreads() API to see it. Thus, the JPDA backend will have a
chance to externally suspend the thread before its THREAD_START event.
In the case of this thread, it self-suspends in
JavaCallWrapper::JavaCallWrapper() just after changing its
ThreadState from _thread_in_vm to _thread_in_Java. It has not yet
run any Java code so _last_Java_sp is NULL.
The VMThread starts a safepoint at the same time that the thread is
trying to self-suspend. If the VMThread makes it past its
is_any_suspended_with_lock() check, it will:
- vm_suspend() the thread
- find the thread in state _thread_in_Java
- call get_top_frame()
- call fetch_top_frame()
- fail an assertion because _last_Java_sp is NULL
The assertion is new with the Itanium merge which is why I didn't see
this problem with my early Mantis stress runs.