JDK-8246442 : nmethod::can_convert_to_zombie() asserts when not called by the sweeper
  • Type: Bug
  • Component: hotspot
  • Sub-Component: jvmti
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2020-06-03
  • Updated: 2024-10-17
  • Resolved: 2020-06-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 15
15 b27Fixed
Related Reports
Relates :  
Description
The following test failed in the JDK15 CI:

serviceability/jvmti/CompiledMethodLoad/Zombie.java

nmethod::can_convert_to_zombie() used to be called only by the sweeper, after it has checked that an nmethod is not entrant. Due to the single call site, there was an assert checking that the nmethod should be not entrant (the condition just checked).
However, it is now used in nmethod::post_compiled_method_load_event(), where the result of the assert is racy.

Crash looks like this:
Current thread (0x00007faf71810620):  JavaThread "Thread-0" daemon [_thread_in_vm, id=6407, stack(0x000070000c38c000,0x000070000c48c000)]

Stack: [0x000070000c38c000,0x000070000c48c000],  sp=0x000070000c48b8e0,  free space=1022k
Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.dylib+0xb3ca44]  VMError::report_and_die(int, char const*, char const*, __va_list_tag*, Thread*, unsigned char*, void*, void*, char const*, int, unsigned long)+0x670
V  [libjvm.dylib+0xb3d16b]  VMError::report_and_die(Thread*, void*, char const*, int, char const*, char const*, __va_list_tag*)+0x47
V  [libjvm.dylib+0x334190]  report_vm_error(char const*, int, char const*, char const*, ...)+0x145
V  [libjvm.dylib+0x8e7ced]  nmethod::can_convert_to_zombie()+0x47
V  [libjvm.dylib+0x8e8e4a]  nmethod::post_compiled_method_load_event(JvmtiThreadState*)+0x2a
V  [libjvm.dylib+0x70b913]  JvmtiCodeBlobEvents::generate_compiled_method_load_events(JvmtiEnv*)+0xdb
V  [libjvm.dylib+0x71fb68]  jvmti_GenerateEvents(_jvmtiEnv*, jvmtiEvent)+0xf7
C  [libCompiledZombie.dylib+0xd35]  GenerateEventsThread+0x45
V  [libjvm.dylib+0x780110]  JvmtiAgentThread::call_start_function()+0x3c
V  [libjvm.dylib+0xab2f73]  JavaThread::thread_main_inner()+0x193
V  [libjvm.dylib+0xaaf6c9]  Thread::call_run()+0x11b
V  [libjvm.dylib+0x9247ec]  thread_native_entry(Thread*)+0xe0
C  [libsystem_pthread.dylib+0x3661]  _pthread_body+0x154
C  [libsystem_pthread.dylib+0x350d]  _pthread_body+0x0
C  [libsystem_pthread.dylib+0x2bf9]  thread_start+0xd
Comments
URL: https://hg.openjdk.java.net/jdk/jdk/rev/620c148da1ed User: eosterlund Date: 2020-06-08 12:24:24 +0000
08-06-2020

I think that the cause for this bug and JDK-8245877 look different. I know the fix to this bug, but it won't solve the other bug.
03-06-2020

This looks similar to following bug that Leonid filed recently: JDK-8245877 assert(_value != __null) failed: resolving NULL _value in JvmtiExport::post_compiled_method_load
03-06-2020

When an nmethod is created, the load event will never be able to see the nmethod spuriously flipping to zombie, because there simply are no safepoint polls/transitions between the nmethod being created and the load event firing. However, the jvmti_GenerateEvents can observe such spurious flips to zombie. It is completely harmless, because the whole operation runs under the CodeCache_lock, which prevents further nmethods from being flushed. But they can flip to zombie, which is indeed exactly what the check is design to test. Therefore, this is just a false positive assertion failure. Proposed fix: make the assert only apply when called from the sweeper thread.
03-06-2020