JDK-8314024 : SIGSEGV in PhaseIdealLoop::build_loop_late_post_work due to bad immediate dominator info
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 17,20,21,22
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2023-08-07
  • Updated: 2024-01-22
  • Resolved: 2023-08-30
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 17 JDK 21 JDK 22
17.0.10-oracleFixed 21.0.1Fixed 22 b13Fixed
Related Reports
Relates :  
Relates :  
Description
ADDITIONAL SYSTEM INFORMATION :
OS X + Linux

A DESCRIPTION OF THE PROBLEM :
JitRex creates bytecode in a pre-stackmaps manner. In some cases, this bytecode can crash the JVM. 

Example provided later in this form.



STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Adjust the path to Java in repro.sh to point to 17.0.8 (and possibly others as well).
Run ./repro.sh
JVM will crash - #  SIGSEGV (0xb) at pc=0x00000001064e5c10, pid=96307, tid=25347

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
JVM should not crash, and executes the bytecode to perform regex matching.
ACTUAL -
JVM crashes: 

# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00000001064e5c10, pid=96307, tid=25347

---------- BEGIN SOURCE ----------
Requires jitrex 0.1.20.jar 
I've also uploaded the .tgz file here: https://filetransfer.io/data-package/rM9xhQMu#link
It should contain 3 files
* jitrex
* repro.sh
* ReproSimple.java

--------- .sh file --------
#!/bin/bash

set -e

LIBS=jitrex-0.1.20.jar

# ADJUST THIS:
JAVA_BIN=/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home/bin

JAVA_FLAGS="-Xms2G -Xmx4G -Xss1M -Xlog:jit*=debug:file=./jit_humio.log:time,tags:filecount=5,filesize=1024000"

javac -classpath ${LIBS} ReproSimple.java
${JAVA_BIN}/java  -classpath .:${LIBS} ${JAVA_FLAGS} ReproSimple

------ Java File --------

import com.humio.jitrex.*;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;

public class ReproSimple {

    final static String regexPattern = "(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}),(\\S+),(\\S+),(\\S+),(\\S+),(\\S+),(\\S+),(\\S+),(\\S+),(\\S+),(\\S+),(.*)";

    public static void main(String[] args) throws InterruptedException {
	System.out.println("Starting");
	work();
	System.out.println("Ended");
    }
    
    static void work() {
	String[] haystack = new String[] {
	    "2023-10-01 01:23:46,warn,maccle,Something happened.",
	    "",
	    "0".repeat(50)
	};

	long sum = 0;
	for (int iter=1; iter<=100; iter++) {
	    System.out.print("("+iter+")");

	    Pattern p = Pattern.compile(regexPattern, 0);
	    Matcher m = p.matcher("");
	    
	    for (int k=0; k<haystack.length; k++) {
		for (int i=0; i < 1 * 1000 ; i++) {
		    m.reset(CharSeq.fromString(haystack[k]));
		    if (m.find()) {
			sum += m.start() + m.end();
		    }
		}
	    }
	}
	if (sum<0) System.out.println(sum);
    }

    static class CharSeq implements CharSequence {
	ByteBuffer buf;
	int start, end;

	public static CharSeq fromString(String s) {
	    CharSeq r = new CharSeq();
	    r.buf = ByteBuffer.wrap(s.getBytes(StandardCharsets.ISO_8859_1));
	    r.start = 0;
	    r.end = r.buf.limit();
	    return r;
	}

	public int length() { return end - start; }

	public char charAt(int index) {
	    if (index < 0 || start + index >= end) throw new IndexOutOfBoundsException("" + index);
	    return (char)(buf.get(start + index) & 0xFF);
	}

	public CharSequence subSequence(int start, int end) {
	    throw new UnsupportedOperationException();
	}
    }
    
}
---------- END SOURCE ----------

FREQUENCY : always



Comments
Fix request (17u, 21u): The fix should be backported, because the issue is reproducible in both jdk17 and jdk21 by test/hotspot/jtreg/compiler/loopopts/TestNodeSunkFromPreLoop.java without the fix. Clean backport, no tier1 regressions, all GHA test passed.
01-09-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk21u/pull/124 Date: 2023-09-01 08:53:11 +0000
01-09-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk17u-dev/pull/1714 Date: 2023-08-31 14:13:35 +0000
31-08-2023

Changeset: ed1ea5fe Author: Roland Westrelin <roland@openjdk.org> Date: 2023-08-30 07:52:05 +0000 URL: https://git.openjdk.org/jdk/commit/ed1ea5fe7c6fad03ca96e7dece2127eab21a608a
30-08-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/15399 Date: 2023-08-23 09:15:38 +0000
23-08-2023

I can reproduce this only with release builds and I think that's just due to different timing. I narrowed it down to JDK-8280799 in JDK 19. The fix was backported to 11u and 17u. The problem is that 'n' is NULL in 'idom_no_update'. In fastdebug, we would hit the "Bad immediate dominator info." assert. I verified this by enabling it in product: # A fatal error has been detected by the Java Runtime Environment: # # Internal Error (loopnode.hpp:1140), pid=292462, tid=292476 # guarantee(n != nullptr) failed: Bad immediate dominator info. # # JRE version: Java(TM) SE Runtime Environment (22.0) (build 22-internal-2023-08-09-1155514.tobias...) # Java VM: Java HotSpot(TM) 64-Bit Server VM (22-internal-2023-08-09-1155514.tobias..., mixed mode, compressed oops, compressed class ptrs, g1 gc, linux-amd64) # Problematic frame: # V [libjvm.so+0xb95489] PhaseIdealLoop::build_loop_late_post_work(Node*, bool)+0x7c9 Current CompileTask: C2: 395 57 % com.humio.jitrex.jvm.R_tmp_102_424e046f_2__28_5cd_7b4_7d_2d_5cd_7b2_7d_2d_5cd_7b2_7d_20_5cd_7b2_7d_3a_5cd_7b2_2e_2e_2e::nextMatchInt @ 64 (3539 bytes) Stack: [0x00007f52eb93b000,0x00007f52eba3c000], sp=0x00007f52eba37550, free space=1009k Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) V [libjvm.so+0xb95489] PhaseIdealLoop::build_loop_late_post_work(Node*, bool)+0x7c9 (loopnode.hpp:1140) V [libjvm.so+0xb95620] PhaseIdealLoop::build_loop_late(VectorSet&, Node_List&, Node_Stack&)+0x170 (loopnode.cpp:6007) V [libjvm.so+0xb95f30] PhaseIdealLoop::build_and_optimize()+0x750 (loopnode.cpp:4468) V [libjvm.so+0x643cc9] Compile::Optimize()+0xc39 (loopnode.hpp:1114) V [libjvm.so+0x6456c2] Compile::Compile(ciEnv*, ciMethod*, int, Options, DirectiveSet*)+0xed2 (compile.cpp:850) V [libjvm.so+0x574079] C2Compiler::compile_method(ciEnv*, ciMethod*, int, bool, DirectiveSet*)+0x159 (c2compiler.cpp:119) V [libjvm.so+0x64b2fe] CompileBroker::invoke_compiler_on_method(CompileTask*)+0xa9e (compileBroker.cpp:2276) V [libjvm.so+0x64e558] CompileBroker::compiler_thread_loop()+0x698 (compileBroker.cpp:1944) V [libjvm.so+0x8f8038] JavaThread::thread_main_inner() [clone .part.0]+0xb8 (javaThread.cpp:720) V [libjvm.so+0xe9aa18] Thread::call_run()+0xa8 (thread.cpp:217) V [libjvm.so+0xcbfaaa] thread_native_entry(Thread*)+0xda (os_linux.cpp:783) Might be similar to JDK-8268261, JDK-8262017. ILW = Crash during C2 compilation, reproducible with framework that generates bytecode, no workaround but disable compilation of affected method(s) = HMM = P2
09-08-2023

Roland, could you please have a look?
09-08-2023

Issue is reproduced. Crash is observed. OS: MacOS (x64) JDK 17.0.8: Fail JDK 20.0.2: Fail JDK 21 ea:Fail JDK 22 ea: Fail ILW = issue in GA build, reproducible with single test , no workaround available = MLM = P4 Moving it to dev team for further analysis
09-08-2023