未添加本机代码的 Java 致命错误 SIGSEGV

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24101142/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 10:09:40  来源:igfitidea点击:

Java fatal error SIGSEGV with no added native code

javasegmentation-faultjvm-hotspotjvm-crash

提问by Hymankamm

I am getting an error message from the Java compiler that I don't understand. I've tested my code on OSX 10.6, 10.9, and Ubuntu 14.04, with both Java 6 and 7. When I run with the Eclipse debugger or from the interpreter (using -Xint option), everything runs fine. Otherwise, I get the following messages:

我从 Java 编译器收到一条我不明白的错误消息。我已经在 OSX 10.6、10.9 和 Ubuntu 14.04 上使用 Java 6 和 7 测试了我的代码。当我使用 Eclipse 调试器或从解释器(使用 -Xint 选项)运行时,一切正常。否则,我会收到以下消息:

Java 1.6:

Java 1.6:

Invalid memory access of location 0x8 rip=0x1024e9660

Java 1.7:

Java 1.7:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x000000010f7a8262, pid=20344, tid=18179
#
# JRE version: Java(TM) SE Runtime Environment (7.0_60-b19) (build 1.7.0_60-b19)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (24.60-b09 mixed mode bsd-amd64 compressed oops)
# Problematic frame:
# V  [libjvm.dylib+0x3a8262]  PhaseIdealLoop::idom_no_update(Node*) const+0x12
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp
#

There's more error output for Java 7 (that is saved to a file) but unfortunately I can't fit it in the character limit of this post. Sometimes I need to run my code a couple of times for the error to come up, but it appears more often than not.

Java 7 有更多错误输出(保存到文件中),但不幸的是,我无法将其放入本文的字符数限制中。有时我需要运行我的代码几次才能出现错误,但它经常出现。

My test case involves cacheing some computations in logarithmic scale. Specifically, given log(X),log(Y),..., I have a small class that computes log(X+Y+...). And then I cache the result in a HashMap.

我的测试用例涉及以对数刻度缓存一些计算。具体来说,给定 log(X),log(Y),...,我有一个计算 log(X+Y+...) 的小类。然后我将结果缓存在 HashMap 中。

Strangely, changing some loop indices seems to make the problem go away. In particular, if I replace

奇怪的是,更改一些循环索引似乎可以使问题消失。特别是,如果我更换

for (int z = 1; z < x+1; z++) {
    double logSummand = Math.log(z + x + y);
    toReturn.addLogSummand(logSummand);
}

with

for (int z = 0; z < x; z++) {
    double logSummand = Math.log(1 + z + x + y);
    toReturn.addLogSummand(logSummand);
}

then I don't get the error message and the program runs fine.

然后我没有收到错误消息并且程序运行良好。

My minimal example is below:

我的最小示例如下:

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class TestLogSum {
    public static void main(String[] args) {

        for (int i = 0; i < 6; i++) {
            for (int n = 2; n < 30; n++) {
                for (int j = 1; j <= n; j++) {
                    for (int k = 1; k <= j; k++) {
                        System.out.println(computeSum(k, j));                       
                    }
                }
            }
        }
    }

    private static Map<List<Integer>, Double> cache = new HashMap<List<Integer>, Double>();
    public static double computeSum(int x, int y) {     
        List<Integer> key = Arrays.asList(new Integer[] {x, y});

        if (!cache.containsKey(key)) {

            // explicitly creating/updating a double[] array, instead of using the LogSumArray wrapper object, will prevent the error
            LogSumArray toReturn = new LogSumArray(x);

            // changing loop indices will prevent the error
            // in particular, for(z=0; z<x-1; z++), and then using z+1 in place of z, will not produce error
//          for (int z = 0; z < x; z++) {
//              double logSummand = Math.log(1 + z + x + y);
            for (int z = 1; z < x+1; z++) {
                double logSummand = Math.log(z + x + y);
                toReturn.addLogSummand(logSummand);
            }

            // returning the value here without cacheing it will prevent the segfault
            cache.put(key, toReturn.retrieveLogSum());
        }
        return cache.get(key);
    }

    /*
     * Given a bunch of logarithms log(X),log(Y),log(Z),...
     * This class is used to compute the log of the sum, log(X+Y+Z+...)
     */
    private static class LogSumArray {      
        private double[] logSummandArray;
        private int currSize;

        private double maxLogSummand;

        public LogSumArray(int maxEntries) {
            this.logSummandArray = new double[maxEntries];

            this.currSize = 0;
            this.maxLogSummand = Double.NEGATIVE_INFINITY;
        }

        public void addLogSummand(double logSummand) {
            logSummandArray[currSize] = logSummand;
            currSize++;
            // removing this line will prevent the error
            maxLogSummand = Math.max(maxLogSummand, logSummand);
        }

        public double retrieveLogSum() {
            if (maxLogSummand == Double.NEGATIVE_INFINITY) return Double.NEGATIVE_INFINITY;

            assert currSize <= logSummandArray.length;

            double factorSum = 0;
            for (int i = 0; i < currSize; i++) {
                factorSum += Math.exp(logSummandArray[i] - maxLogSummand);
            }

            return Math.log(factorSum) + maxLogSummand;
        }
    }
}

采纳答案by Hymankamm

So after reading the comments, it seems like this is a bug in the JVM that needs to be reported to Oracle. So, I have gone ahead and filed a bug report to Oracle. I'll post updates when I hear back from them.

所以看了评论,看来这是JVM中的一个bug,需要上报给Oracle。所以,我已经继续向 Oracle 提交了错误报告。当我收到他们的回复时,我会发布更新。

Thanks to all those who tried the code and found it breaks on your machines as well.

感谢所有尝试代码并发现它在您的机器上也损坏的人。

If there is anyone with the ability/inclination to figure out what code in the compiler is causing this error, it would be awesome to hear about it :)

如果有人有能力/倾向于找出导致此错误的编译器中的代码,那么听到它会很棒:)

UPDATE:Someone from Oracle responded yesterday, he said he prepared a fix for the bug and also asked to include my code as a regression test :) He didn't explain what the problem was, beyond saying it was in the HotSpot JIT, but he did send me a link with the changes he made, in case anyone is interested: http://cr.openjdk.java.net/~kvn/8046516/webrev/

更新:昨天 Oracle 的某个人做出了回应,他说他为这个错误准备了一个修复程序,并要求将我的代码作为回归测试包括在内 :) 他没有解释问题是什么,只是说它出在 HotSpot JIT 中,但是他确实给我发送了一个包含他所做更改的链接,以防有人感兴趣:http: //cr.openjdk.java.net/~kvn/8046516/webrev/