Thread::current() and JNI pthread interaction

David Simms david.simms at
Wed Feb 5 08:15:18 PST 2014

This looks like a bug unfortunately, the JNI documentation doesn't 
appear to warn against this kind of use.

The code in question:

	static void make_key()
		pthread_key_create(&key, detachThread);

	 *  pthread key destructor (runs after the JVM current thread key is already destroyed)
	static void detachThread(void *p)
		if (p != 0)
			JavaVM *jvm = 0;
			JNIEnv *env = (JNIEnv *) p;
			*jint result = jvm->DetachCurrentThread();*

The JVM current thread is already toast as you suggest.

I believe Andreas that you might already have a simple pain free 
work-around from the JVM. Given that the problem only appears on certain 
platforms, there may be other case where people migrate to 64 bit and 
find this nasty crash. Be worth filing a bug...

/David Simms

On 02/05/2014 12:47 PM, Andreas Eriksson wrote:
> Hi,
> I'm investigating a bug where JNI code (attached, compilation 
> instructions below) is using pthread_key_create with a destructor to 
> detach the thread from the JVM when the thread is exiting.
> This solution works well when running on Solaris or a 32 bit JVM on 
> Linux, but when run on 64 bit JVM on Linux the threads hang when 
> detaching.
> It turns out that for 64 bit Linux the JVM is also using the 
> pthread_key_create, to store the Thread::current() value in a thread 
> local storage.
> Ssince the thread local storages are reset in Thread::~Thread 
> (ThreadLocalStorage::set_thread(NULL)), before the JNI destructor 
> runs, we run detachCurrentThread on a thread that has NULL as current 
> thread.
> With a product build this breaks locks/monitors, and the threads hang. 
> With a debug build an assert in Thread::current() is hit instead.
> Everything works if detachCurrentThread is called from the main logic 
> instead.
> Is this considered a bug, or maybe this behavior is expected?
> Regards,
> Andreas
> Compile native:
> # 64bit
> JAVA_HOME=/java/linux-x64/jdk1.7.0_45
> gcc -shared -fpic  -o  -I$JAVA_HOME/include 
> -I$JAVA_HOME/include/linux -lstdc++ Callback_Native.cpp
> # 32bit
> JAVA_HOME=/java/linux-i586/jdk1.7.0_45
> gcc -v -m32 -shared -fpic  -o  -I$JAVA_HOME/include 
> -I$JAVA_HOME/include/linux -lstdc++ Callback_Native.cpp
> Compile java (from callback/src/main/java):
> JAVA_HOME=/java/linux-x64/jdk-1.7.0_45
> $JAVA_HOME/bin/javac com/test/callback/
> $JAVA_HOME/bin/javac com/test/callback/
> To run: (from callback/src/main/java)
> NATIVE=../../../native
> $JAVA_HOME/bin/java -Djava.library.path=$NATIVE com.test.callback.App

-------------- next part --------------
An HTML attachment was scrubbed...

More information about the hotspot-runtime-dev mailing list