JDK-8369250 : Assess and remedy any unsafe usage of the Semaphore used by NonJavaThread::List
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 11.0.7,12
  • Priority: P3
  • Status: New
  • Resolution: Unresolved
  • Submitted: 2025-10-07
  • Updated: 2025-10-07
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 26
26Unresolved
Related Reports
Causes :  
Relates :  
Description
As per JDK-8361462 we have seen the following crash:

# assert(kr == 0 || kr == 49) failed: Failed to timed-wait on semaphore: Unknown (0xf) 

where that error code corresponds to:

#define KERN_INVALID_NAME 15 

--------------- T H R E A D ---------------

Current thread (0x000000014702b010): VMThread "VM Thread" [id=19459, stack(0x000000016fe10000,0x0000000170013000) (2060K)]

Stack: [0x000000016fe10000,0x0000000170013000], sp=0x0000000170012ca0, free space=2059k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [libjvm.dylib+0x12361c4] VMError::report(outputStream*, bool)+0x1b00 (semaphore_bsd.cpp:112)
V [libjvm.dylib+0x1239a64] VMError::report_and_die(int, char const*, char const*, char*, Thread*, unsigned char*, void const*, void const*, char const*, int, unsigned long)+0x55c
V [libjvm.dylib+0x5ae4e8] print_error_for_unit_test(char const*, char const*, char*)+0x0
V [libjvm.dylib+0xff1324] SerialArguments::initialize()+0x0
V [libjvm.dylib+0x103f210] SingleWriterSynchronizer::synchronize()+0xc8
V [libjvm.dylib+0xe8f3c4] NonJavaThread::remove_from_the_list()+0xd4
V [libjvm.dylib+0xe8f5cc] NonJavaThread::post_run()+0x1c
V [libjvm.dylib+0x1176dec] Thread::call_run()+0x134
V [libjvm.dylib+0xed9724] thread_native_entry(Thread*)+0x138
C [libsystem_pthread.dylib+0x6fa8] _pthread_start+0x94
VM_Operation (0x00000001042b8ee8): Halt, mode: safepoint

There is a general race between statically allocated Semaphore objects being destroyed by libc as the process exits, and concurrently running threads in the JVM at termination time. The VMThread example above arises after the VMThread has logically exited, allowing the DestroyJavaVM thread to invoke `exit()` in the launcher, and the VMThread then tries to clean itself up by removing itself from the `NonJavaThread` list. The same problem can occur with GC threads.

The NonJavaThread::List has a statically allocated instance which contains a SingleWriterSynchronizer, which contains a Semaphore.

Simplest fix is to change the List instance to a DeferredStatic such that it is never destroyed (which avoids other potential issues with threads removing themselves from the list after it has been deallocated).
Comments
A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/27664 Date: 2025-10-07 06:13:51 +0000
07-10-2025