|
Quick Lists
|
|
Bug ID:
|
6219874
|
|
Votes
|
0
|
|
Synopsis
|
JNI document should say to invoke "DetachCurrentThread()" on thread exit
|
|
Category
|
java:native_interface
|
|
Reported Against
|
1.4.2_06
|
|
Release Fixed
|
mustang(beta)
|
|
State
|
10-Fix Delivered,
bug
|
|
Priority:
|
3-Medium
|
|
Related Bugs
|
6282335
|
|
Submit Date
|
21-JAN-2005
|
|
Description
|
JVM crashes in an application using JNI feature.
CONFIGURATION :
JRE/JDK : 1.3.1_11/1.4.2_06
OS : Solaris 8(T2) and Solaris 9
REPRODUCE :
1) Compile the attached X.java in 1.4.2_06
---- X.java --->
class X
{
static {
System.loadLibrary("X");
}
static native void xxx();
public static void main(String[] arg) throws Exception
{
for (int i = 0 ; i < 10 ; ++i) {
xxx();
Thread.sleep(1000);
}
}
}
<---
2) Compile the attached x.c
--- x.c --->
#include <jni.h>
#include <thread.h>
static JavaVM *jvm = NULL;
static void *zzz(void *arg)
{
int n;
JNIEnv *env;
printf("zzz %x\n", &n);
(*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
/* (*jvm)->DetachCurrentThread(jvm); */
}
/*
* Class: X
* Method: xxx
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_X_xxx(JNIEnv *env, jclass klass)
{
thread_t tid;
if (NULL == jvm)
(*env)->GetJavaVM(env, &jvm);
thr_create(0, 0, zzz, 0, 0, &tid);
}
<---
ex.
cc -G -I/java/jdk1.4.2_06/solaris/include -I/java/jdk1.4.2_06/solaris/include/solaris x.c -o libX.so
3) Launch
"env LD_LIBRARY_PATH=/usr/lib/lwp:. ; java X"
The follwoing message will show up.
---->
% env LD_LIBRARY_PATH=/usr/lib/lwp:. ; java X
zzz f1efbf98
zzz f1efbf98
#
# HotSpot Virtual Machine Error, Internal Error
# Please report this error at
# http://java.sun.com/cgi-bin/bugreport.cgi
#
# Java VM: Java HotSpot(TM) Client VM (1.4.2_06-b03 mixed mode)
#
# Error ID: 5448524541442C4F43414C33544F524147450E4350500058 01
#
# Problematic Thread: prio=16777216 tid=0x000ec390 nid=0x9 runnable
#
Heap at VM Abort:
Heap
def new generation total 2112K, used 121K [0xf2000000, 0xf2220000, 0xf2710000
)
eden space 2048K, 5% used [0xf2000000, 0xf201e580, 0xf2200000)
from space 64K, 0% used [0xf2200000, 0xf2200000, 0xf2210000)
to space 64K, 0% used [0xf2210000, 0xf2210000, 0xf2220000)
tenured generation total 1408K, used 0K [0xf2710000, 0xf2870000, 0xf6000000)
the space 1408K, 0% used [0xf2710000, 0xf2710000, 0xf2710200, 0xf2870000)
compacting perm gen total 4096K, used 966K [0xf6000000, 0xf6400000, 0xfa000000
)
the space 4096K, 23% used [0xf6000000, 0xf60f1b00, 0xf60f1c00, 0xf6400000)
Abort
%
<---
WORKAROUND :
To invoke DetachCurrentThread() on thread exit
(Please see the line commended out in the test case.)
REQUEST :
To mention explicitly "JNI user should invoke DetachCurrentThread() on thread exit"
in JNI document.
REPORT(1.4.2_06) :
The program terminates at
guarantee(get_thread() == thread, "must be the same thread, quickly");
in ThreadLocalStorage::set_thread.
get_thread_via_cache_slowly which is called in get_thread sets cache.
Stack pointer is used as cache entry key.
According to the message which the test program outputs,
When runtime uses T2 lib, there seems the case which the stack area , which was used
by exited thread come to be used by another thread. The cache system does not seem to
work well.
This is because stack pointer is used as cache entry key.
Actually, the test program works well in 5.0fcs. In 5.0fcs, thread ID is used
as cache entry key.
So, the abnormal termination does not occur.
xxxxx@xxxxx 2005-1-21 00:50:11 GMT
|
|
Work Around
|
N/A
|
|
Evaluation
|
The document should indicate jni_DetachCurrentThread is mondatory since if not called, the JavaThread will not be cleared and removed from Thread list. More important the cache will be cleared. There will be some memory leak without calling the function too.
The senario in this test case without Detach:
thread 1 created, executes xxx, attached to JavaThread, note a JavaThread will be creadted, because get_thread_slow will get a NULL back. Afer new JavaThread created and initialized, the cache will contains "this" threadi(JavaThread will run too, set the cache slot) . Then thread 1 exit, lead to a JavaThread remains in Thread list.
thread 2 created, executes xxx, reuse the stack region by thread 1 (why not? OS will manage to do this), attach to a JavaThread, same as above, a new JavaThread will be created since under this thread context, thread_get_slow will return NULL. the JavaThread will be init'ed too, and put into Thread local Storage. At the initialization stage, the corresponding cache slot (to this thread) already store a JavaThread of 1, so the guarantee failed.
1.5 overwrite the slot in init stage, so it will not crash.
While jni_DetachCurrentThread called, the cache slot will be reset, so there is no cache hit, will get from slow path.
This is not a bug, customer should pay attention to the usage of attaching threads.
xxxxx@xxxxx 2005-05-25 21:39:47 GMT
reassign to PDE for further proposal.
xxxxx@xxxxx 2005-06-28 19:58:04 GMT
Posted Date : 2005-10-13 18:28:00.0
JNI spec was updated as suggested.
Posted Date : 2005-12-15 21:27:38.0
|
|
Comments
|
Submitted On 26-APR-2007
I think that it is a fucking bad bug!!!!!!
PLEASE NOTE: JDK6 is formerly known as Project Mustang
|
|
|
 |