JDK-8184339 : Thread::current_or_null() shall not assert if Posix TLS is not yet initialized
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 10
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2017-07-13
  • Updated: 2017-08-25
  • Resolved: 2017-07-18
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.
JDK 10
10 b21Fixed
Related Reports
Relates :  
Relates :  
Description
We have Thread::current() and Thread::current_or_null() - the former asserts if not current thread pointer is registered in TLS, the latter does not but returns NULL.

Thread::current() may be implemented via C++ compiler based tls (__thread) or with Posix TLS (pthread_set_specific etc). 

If Posix TLS must be initialized. It is initialized in os::init(). If Thread::current() or Thread::current_or_null() are called before that point, they will assert because TLS is not yet initialized.

Unfortunately, since "JDK-8183925: Decouple crash protection from watcher thread", Thread::current_or_null() may be called before os::init() had a chance to initialized TLS, from within os::malloc, during the initialization of the logging system:

read(??, ??, ??) at 0x900000000346c78
__filbuf(??) at 0x900000000344554
fgetc(??) at 0x90000000040f1d8
getchar() at 0x9000000004c1d7c
ThreadLocalStorage::thread()(), line 58 in "threadLocalStorage_posix.cpp"
Thread::current_or_null()(), line 677 in "thread.hpp"
os::malloc(unsigned long,MemoryType,const NativeCallStack&)(size = 12, memflags = mtLogging, stack = &(...)), line 579 in "os.cpp"
os::malloc(unsigned long,MemoryType)(size = 12, flags = mtLogging), line 570 in "os.cpp"
os::strdup(const char*,MemoryType)(str = "all=warning", flags = mtLogging), line 522 in "os.cpp"
LogOutput::set_config_string(const char*)(this = 0x09001000a0a3f238, string = "all=warning"), line 46 in "logOutput.cpp"
LogStdoutOutput::LogStdoutOutput()(this = 0x09001000a0a3f238), line 64 in "logFileStreamOutput.hpp"
LogFileStreamInitializer::LogFileStreamInitializer()(this = 0x09001000a0854e88), line 47 in "logFileStreamOutput.cpp"

This could be fixed in a number of ways, but we think the best way to fix this would be to make Thread::current_or_null() return NULL if it is called before Posix TLS is initialized. This is because every caller assumed Thread::current_or_null() to be safe and non-asserting (as opposed to Thread::current()). Another benefit would be that error reporting would be more robust, because Thread::current_or_null() is used during error reporting. Asserts into Thread::current_or_null() lead to infinite recursion during error reporting and therefore unusable hs-err files.
Comments
I do not like the fix for this. First, the whole point of the assert is to detect potentially "dangerous" changes to initialization behaviour. It may be that the changes in JDK-8183925 need to be re-examined. Second, I dislike the need to check that it is safe to call something, when the check is generally only needed for one case - the case where the call was "too early".
31-07-2017