spring-projects / spring-loaded

Java agent that enables class reloading in a running JVM
Apache License 2.0
2.72k stars 515 forks source link

Using double[] arrays in constructors crashes jvm #188

Open make opened 7 years ago

make commented 7 years ago

Using lambda expression in Grails 3.2.3 (spring loaded 1.2.6) causes JVM (1.8.0_111-b14) to crash.

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f497380b27b, pid=710, tid=0x00007f493d14b700
#
# JRE version: Java(TM) SE Runtime Environment (8.0_111-b14) (build 1.8.0_111-b14)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.111-b14 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# V  [libjvm.so+0x37127b]  GraphBuilder::try_inline_full(ciMethod*, bool, Bytecodes::Code, Instruction*)+0x2fb
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/markus/git/lambda-reload-bug/hs_err_pid710.log
#
# Compiler replay data is saved as:
# /home/markus/git/lambda-reload-bug/replay_pid710.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
#

The workaround is to disable class reloading in build.gradle with

grails {
    agent {
        enabled = false
    }
}

This can be reproduced with Grails app: https://github.com/make/lambda-reload-bug

make commented 7 years ago

Found that lambda expressions seem to have nothing to do with this issue.

Updated https://github.com/make/lambda-reload-bug to contain only code that crashes the JVM.

To sum up, calling Bug.crash() crashes JVM when having following code:

package crash;

import com.google.common.collect.MinMaxPriorityQueue;

public class Foo {

    class Sub {
        Sub(double[] data) {}
    }

    public Foo() {}

    public void bar(double[] data, int size) {
        new Sub(data);
        MinMaxPriorityQueue.expectedSize(size);
    }

}
package crash;

public class Bug {

    public static void crash() {
        System.out.println("foo");
        Foo foo = new Foo();
        while(true)
            foo.bar(new double[]{}, 10);
    }

}

Weird thing is that neither of following crashes the JVM:

    public void bar(double[] data, int size) {
//        new Sub(data);
        MinMaxPriorityQueue.expectedSize(size);
    }

or

    public void bar(double[] data, int size) {
        new Sub(data);
//        MinMaxPriorityQueue.expectedSize(size);
    }