JDK-8068909 : SIGSEGV in c2 compiled code with OptimizeStringConcat
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 8u20
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2015-01-13
  • Updated: 2017-05-24
  • Resolved: 2015-01-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 7 JDK 8 JDK 9
7u171Fixed 8u60Fixed 9 b49Fixed
Description
I investigated a crash with jdk8_u25. The problem can not be reproduced after
RFR(XS): 8030976: untaken paths should be more vigorously pruned at highest optimization level.

There are more uncommon traps in the code. The resulting graph is smaller and looks different.

However, if this change is reverted, the crash can be produced by the current OpenJDK vm.

The jvm crashes with a segv in c2 compiled code.

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000002ba2912, pid=6588, tid=11664
#
# JRE version: Java(TM) SE Runtime Environment (8.0_25-b18) (build 1.8.0_25-b18)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.25-b02 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# J 20 C2 TestArgumentSyntax2.checkArgumentSyntax(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z (357 bytes) @ 0x0000000002ba2912 [0x0000000002ba2420+0x4f2]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp
#


The crashing method checks the syntax of a string and assembles an error message by concatenating strings. 
I tracked down the bug and found that the load that results in the crash is inserted during PhaseStringOpts::replace_string_concat.
A string, that is already checked for null, is an argument to Stringbuilder.append. Another argument is a single char in a char array. With OptimizeStringConcat the call to Stringbuilder.append is replaced by GraphKit code. A LoadI node is inserted, in order to load the length of the argument string. The control input of the load node is set to kit.control. However, the current control is the range check for the array access to load the char argument from the char-array.

After String Optimization:

{code}
.                     25: ConP: Null                  494: Phi
                              +                       +  +
                              |                       |  |
                              +-> 918: CmpP <---------+  |
                                      +                  |
                                      |                  |
                                      v                  |
                                 919: Bool:ne            |
                                      +                  |
623: CastII     ConI: 1               |                  |
   +               +                  v                  |
   |               |               1522: If              |
   +-> 691: CmpU <-+                  +                  |
           +                          |                  |
           |                          +->1525: IfTrue    |
           v                                  +          |
      629: Bool:gt                            |          v
           +                                  +--> 1526: CastPP
           |                                        +
           v                                        |
       1814: If                                     v
           +                                     2147:AddP
           |                                        +
           +--------> 1815: IfTrue                  |
                               +                    v
                               +---------------> 2148: LoadI
							   
{code}

Before Matching:

{code}
691: CmpU                   494: Phi
    +                           +
    |                           |
    v                           |
3035: Bool:le                   |
    +                           |
    |                           |
    v                           |
3091: If                        |
    +                           v
    |                        2147: AddP
    +---> 3092: IfFalse         +
                  +             |
                  |             v
                  +-------> 2148: LoadI
{code}				  

				  
During IGVN the graph is scanned for a nullcheck for the LoadI-node. But only if its control input is set to null. During IGVN, the CastPP first changes its type to NotNull and is removed later.

If-node 1814 is dominated by If-node 1522, but is hoisted to an other if with the same condition.

Fix: Set the control of 2148 LoadI, to NULL. In this case, its corresponding nullcheck will be found as required edge to 1526: CastPP (MemNode::Ideal_common_DU_postCCP).

The problem can not be reproduced after
RFR(XS): 8030976: untaken paths should be more vigorously pruned at highest optimization level.

There are more uncommon traps in the code. The resulting graph is smaller and looks different.
If this change is reverted, the crash can be produced by the current OpenJDK vm.

With JDKs > 7, there is no count field in the Sting-object. In order to determine the length, the char-array is loaded and it's size is taken. In this case the crash happens during a loadN with a graph, that is slightly more complicated.
Comments
8u40-defer-request justification: the problem is not reproducible in 8u40 and 9 (still present but very rare) after 8030976 changes were pushed in jdk9 and jdk8u40. The customer (SAP) agreed to defer it to 8u60.
23-01-2015

ILW=Crash, occured outside regular testing, -XX:-OptimizeStringConcat=HLM=P3
14-01-2015