openjdk9 on Freebsd

Thomas Stüfe thomas.stuefe at gmail.com
Thu Mar 17 09:31:15 UTC 2016


Hi Brian,


> The next patches where less straightforward.  When running java I was
> getting a ton of messages like:
> Thread 832744400 has exited with leftover thread-specific data after 4
> destructor iterations
> After doing a lot of digging and debugging on Linux, I found the code path
> for Linux was identical for Freebsd and the cleanup destructor was being
> executed 4 times just like Freebsd, the difference being that Freebsd would
> print out this benign warning while Linux would just ignore it.  The
> problem is that all threads that are created and initialize TLS current
> thread data, must clean them up by explicitly setting the TLS current
> thread to null.  I’ve come up with two approaches to accomplish this.
>
> clean up TLS current thread at end of ::run functions similar to how it's
> done in openjdk8.
>
> http://brian.timestudybuddy.com/webrev/hotspot__clear_thread_current/webrev/
> clear current thread before exiting java_start to avoid warnings from
> leftover pthread_setspecific data
>
> http://brian.timestudybuddy.com/webrev/hotspot__clear_thread_current_alt/webrev/
>
>
>
I do not think this is a real leak. From what I remember of how the glibc
implements TLS, setting the TLS slot value to NULL would not in itself
delete anything. In VM, this slot keeps the pointer to the current Thread*,
which is correctly deleted at the end of the thread (void
JavaThread::thread_main_inner()).

Digging further, I found the pthread key destructor
"restore_thread_pointer(void* p)" in threadLocalStorage_posix.cpp:

// Restore the thread pointer if the destructor is called. This is in case
// someone from JNI code sets up a destructor with pthread_key_create to run
// detachCurrentThread on thread death. Unless we restore the thread
pointer we
// will hang or crash. When detachCurrentThread is called the key will be
set
// to null and we will not be called again. If detachCurrentThread is never
// called we could loop forever depending on the pthread implementation.
extern "C" void restore_thread_pointer(void* p) {
  ThreadLocalStorage::set_thread((Thread*) p);
}

So, it seems we even reset deliberately the thread pointer to a non-NULL
value. The comment claims that we reset the Thread* value in case there is
another user-provided destructor which runs afterwards and which
does detachCurrentThread () which would require Thread::current() to work.
But there a details I do not understand:

- At this point, should the Thread* object not already be deallocated, so
this would be a dangling pointer anyway?

- Also, according to Posix, this is unspecified. Doc on
pthread_setspecific() states: "Calling pthread_setspecific() from a
thread-specific data destructor routine may result either in lost storage
(after at least PTHREAD_DESTRUCTOR_ITERATIONS attempts at destruction) or
in an infinite loop."

- In jdk8, we did reset the slot value to NULL before Thread exit. So, in
this case detachCurrentThread() from a pthread_key destructor should not
have worked at all.

Could someone from Oracle maybe shed light on this?

Kind Regards, Thomas


With all these patches I’ve accomplished my initial goal of getting Freebsd
> to build cleanly and compile and run HelloWorld cleanly on Freebsd
>
> Thanks,
> Brian Gardner
>
>
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/bsd-port-dev/attachments/20160317/88283e81/attachment.html>


More information about the bsd-port-dev mailing list