JDK-8340313 : Crash due to invalid oop in nmethod after C1 patching
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 11,17,21,23,24
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux
  • CPU: x86_64
  • Submitted: 2024-09-17
  • Updated: 2024-12-30
  • Resolved: 2024-10-17
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 21 JDK 23 JDK 24
21.0.7-oracleFixed 23.0.2Fixed 24 b20Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
STDOUT:
config common.TransformationWarningsTest.setup(): success
0: waiting for barrier
5: waiting for barrier
6: waiting for barrier
7: waiting for barrier
8: waiting for barrier
3: waiting for barrier
9: waiting for barrier
4: waiting for barrier
2: waiting for barrier
1: waiting for barrier
1: starting iterations
0: starting iterations
5: starting iterations
6: starting iterations
7: starting iterations
8: starting iterations
9: starting iterations
3: starting iterations
4: starting iterations
2: starting iterations
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f708ee96c68, pid=3758869, tid=3759192
#
# JRE version: OpenJDK Runtime Environment (24.0) (build 24)
# Java VM: OpenJDK 64-Bit Server VM (24, compiled mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# V  [libjvm.so+0x7dfc68]  RegisterNMethodOopClosure::do_oop(oopDesc**)+0x38
#
# Core dump will be written. Default location: /tmp/tone/run/jtreg/jt-work/jtreg/test_jaxp/javax/xml/jaxp/unittest/common/TransformationWarningsTest/core.3758869
#
# An error report file with more information is saved as:
# /tmp/tone/run/jtreg/jt-work/jtreg/test_jaxp/javax/xml/jaxp/unittest/common/TransformationWarningsTest/hs_err_pid3758869.log
#
# If you would like to submit a bug report, please visit:
#   mailto:yansendao.ysd@alibaba-inc.com
#
Comments
Fix request [21u] I backport this for parity with 21.0.7-oracle. Medium risk, locking is fragile, and the patch is not productive yet. Trivial resolves needed. Test passes but also without the patch. SAP nightly teting passed.
24-12-2024

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk21u-dev/pull/1284 Date: 2024-12-23 09:45:14 +0000
23-12-2024

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk23u/pull/189 Date: 2024-10-17 05:44:13 +0000
17-10-2024

[jdk23u-fix-request] Intermittent crashes in GC when patching C1 compiled code. Fix is low risk (extending scope of lock). Applies cleanly on all platforms except riscv (easy to resolve). Tier1-3 passed.
17-10-2024

Changeset: 58d39c31 Branch: master Author: Tobias Hartmann <thartmann@openjdk.org> Date: 2024-10-17 05:03:09 +0000 URL: https://git.openjdk.org/jdk/commit/58d39c317e332fda994f66529fcd1a0ea0e53151
17-10-2024

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/21389 Date: 2024-10-07 13:39:28 +0000
07-10-2024

The problem is that the code in 'Runtime1::patch_code' is not thread-safe because one thread can update the oop immediate of the 'mov' in the patch body: https://github.com/openjdk/jdk/blob/212e32931cafe446d94219d6c3ffd92261984dff/src/hotspot/share/c1/c1_Runtime1.cpp#L1185 While another thread walks the nmethod oops (via Universe::heap()->register_nmethod(nm)) and then encounters a half-written oop if the immediate crosses a page or cache-line boundary: https://github.com/openjdk/jdk/blob/212e32931cafe446d94219d6c3ffd92261984dff/src/hotspot/share/c1/c1_Runtime1.cpp#L1282 Updating the oop immediate is not atomic because the address of the immediate is not 8-byte aligned. I think we could simply align it in 'PatchingStub::emit_code': diff --git a/src/hotspot/cpu/x86/c1_CodeStubs_x86.cpp b/src/hotspot/cpu/x86/c1_CodeStubs_x86.cpp index 71ca9351f86..7b69201cbde 100644 --- a/src/hotspot/cpu/x86/c1_CodeStubs_x86.cpp +++ b/src/hotspot/cpu/x86/c1_CodeStubs_x86.cpp @@ -333,6 +333,7 @@ void PatchingStub::emit_code(LIR_Assembler* ce) { #ifdef ASSERT address start = __ pc(); #endif + __ align(8, __ offset() + 2); // 8-byte align the immediate to guarantee atomic access when patching jobject o = nullptr; __ movoop(_obj, o); #ifdef ASSERT
30-09-2024

I was able to extract a simple test (see attached Test.java) that reproduces the issue on Linux x64 with a release build. ILW = Crash due to invalid oop when GC walks nmethod oops after C1 patching, reproducible but intermittent and edge case, no workaround but disable compilation of affected method or make sure that class is loaded to prevent patching = HMM = P2
25-09-2024

Seems to be an old issue. I can already reproduce this with JDK 11 b28: -Xcomp -ea -esa -XX:TieredStopAtLevel=3 -XX:CompileCommand=quiet -XX:CompileCommand=compileonly,com.sun.org.apache.xalan.internal.xsltc.compiler.Parser::initSymbolTable # A fatal error has been detected by the Java Runtime Environment: # # SIGSEGV (0xb) at pc=0x00007fa1b1c63ed1, pid=2539831, tid=2539853 # # JRE version: Java(TM) SE Runtime Environment (11.0+28) (build 11+28) # Java VM: Java HotSpot(TM) 64-Bit Server VM (11+28, compiled mode, tiered, compressed oops, g1 gc, linux-amd64) # Problematic frame: # V [libjvm.so+0x85fed1] HeapRegion::add_strong_code_root_locked(nmethod*)+0x1 # # Core dump will be written. Default location: Core dumps may be processed with "/opt/core.sh %p" (or dumping to /opt/mach5/mesos/work_dir/slaves/a20696e7-ae7d-4d37-8e9c-83f99ef002cb-S27843/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-0196/executors/a6e64940-3f94-4cfd-85cc-bd80c9691d60/runs/ebf10adf-0e98-414b-a6c1-a6ad1b7bdfb0/testoutput/jtreg/JTwork/javax/xml/jaxp/unittest/common/TransformationWarningsTest/core.2539831) # # If you would like to submit a bug report, please visit: # http://bugreport.java.com/bugreport/crash.jsp # Stack: [0x00007fa17e4ca000,0x00007fa17e5cb000], sp=0x00007fa17e5c52e0, free space=1004k Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code) V [libjvm.so+0x85fed1] HeapRegion::add_strong_code_root_locked(nmethod*)+0x1 V [libjvm.so+0x79e717] G1CollectedHeap::register_nmethod(nmethod*)+0x37 V [libjvm.so+0x56cd97] Runtime1::patch_code(JavaThread*, Runtime1::StubID)+0x707 V [libjvm.so+0x56ee3e] Runtime1::move_mirror_patching(JavaThread*)+0xe v ~RuntimeStub::load_mirror_patching Runtime1 stub J 102 c1 com.sun.org.apache.xalan.internal.xsltc.compiler.Parser.initSymbolTable()V java.xml@11 (1557 bytes) @ 0x00007fa195380cb7 [0x00007fa19537be00+0x0000000000004eb7] j com.sun.org.apache.xalan.internal.xsltc.compiler.Parser.init()V+146 java.xml@11 j com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC.reset()V+105 java.xml@11 The relevant method can be found here: https://github.com/openjdk/jdk/blob/master/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java#L745
18-09-2024

Moving to the compiler for initial assessment because G1 crashes when we're patching C1 code: V [libjvm.so+0x7dfc68] RegisterNMethodOopClosure::do_oop(oopDesc**)+0x38 (g1CollectedHeap.cpp:2964) V [libjvm.so+0x7d6691] G1CollectedHeap::register_nmethod(nmethod*)+0x31 (nmethod.hpp:840) V [libjvm.so+0x5763a9] Runtime1::patch_code(JavaThread*, Runtime1::StubID)+0x639 (c1_Runtime1.cpp:1275) V [libjvm.so+0x577517] Runtime1::access_field_patching(JavaThread*)+0x17 (c1_Runtime1.cpp:1428) v ~RuntimeStub::access_field_patching Runtime1 stub 0x00007f7077b109b8 J 14856 c1 com.sun.org.apache.xalan.internal.xsltc.compiler.Parser.initSymbolTable()V java.xml@24 (1566 bytes) @ 0x00007f7071bbe039 [0x00007f7071bb8b80+0x00000000000054b9]
17-09-2024