JDK-8278309 : [windows] use of uninitialized OSThread::_state
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 11,17,18
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows
  • Submitted: 2021-12-06
  • Updated: 2022-02-10
  • Resolved: 2021-12-08
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 11 JDK 13 JDK 15 JDK 17 JDK 18 JDK 19
11.0.15-oracleFixed 13.0.11Fixed 15.0.7Fixed 17.0.3-oracleFixed 18 b27Fixed 19Fixed
Related Reports
Duplicate :  
Relates :  
Description
On Windows, we use `OSThread::_state` in `os::create_thread` before it has been initialized. This causes asserts to fire in `Thread::is_JavaThread_protected` (`assert(target->is_handshake_safe_for(current_thread)`)

Only happens if the following is true:
- We log os=info level, thereby firing the "Thread started.." log output the parent thread of a newly started child thread writes. Since JDK-8268773, we also print the thread name. `Thread::name()` uses `Thread::is_JavaThread_protected`, but on Windows the thread state has not been set yet.
- This is an assert, so only debug, but in debug newly malloced memory is poisened with "F1F1F1F1...", which hides the error since  `Thread::is_JavaThread_protected` compares the thread state like this:
```
  if (target->osthread() == NULL || target->osthread()->get_state() <= INITIALIZED) {
    return true;
  }
```
and the compiler interprets the "F1F1F1F1"-filled enum as a signed integer and hence a negative large value. Changing the init pattern to 0x01, or adding an explicit cast to unsigned, causes the assert to fire as soon as logging is switched on.


Comments
A pull request was submitted for review. URL: https://git.openjdk.java.net/jdk15u-dev/pull/173 Date: 2022-02-10 14:41:50 +0000
10-02-2022

Fix request (13u, 15u): the fix applies cleanly to 15u, and skara-cleanly to 13u.
10-02-2022

A pull request was submitted for review. URL: https://git.openjdk.java.net/jdk13u-dev/pull/325 Date: 2022-02-10 14:20:17 +0000
10-02-2022

A pull request was submitted for review. URL: https://git.openjdk.java.net/jdk17u-dev/pull/86 Date: 2022-01-13 08:56:32 +0000
13-01-2022

Fix Request: This is a potential bug, even if it seems benign, and the fix is very trivial. I'd like to fix this therefore in JDK 11 and JDK 17. Oracle already backported it to 11 and 17. JDK11: does not apply cleanly, but the required changes are trivial. JDK17: applies cleanly. Risk: none. Fix is very trivial. Thanks, Thomas
15-12-2021

Changeset: 54993b13 Author: Thomas Stuefe <stuefe@openjdk.org> Date: 2021-12-08 09:18:58 +0000 URL: https://git.openjdk.java.net/jdk/commit/54993b13078ceb05736bb0e1d7ed7415c390442e
08-12-2021

ILW = MLM = P4
07-12-2021

[~dholmes] Yes, that's the fix I plan to do. Just wanted to have a negative before having the fix, since it's not possible to have a regression test atm since we cannot influence the heap init word via command line. So I set init word to 0x01: https://github.com/tstuefe/jdk/runs/4434547750?check_suite_focus=true , and I also was curious if anything else breaks. Now I can do the patch and see it working :)
07-12-2021

Trivial fix: // Allocate the OSThread object OSThread* osthread = new OSThread(NULL, NULL); if (osthread == NULL) { return false; } +osthread->set_state(ALLOCATED);
07-12-2021

Ugghh! We have two different places where we construct and then initialize the OSThread on Windows and one of them is broken. Ideally we would always use create_os_thread() or at least the same logic. Unclear why Windows skips the ALLOCATED state.
07-12-2021