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

2023-11-25

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

Java 1.6:

Invalid memory access of location 0x8 rip=0x1024e9660

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
#

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

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

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

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);
}

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

我的最小示例如下:

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;
        }
    }
}

因此,在阅读评论后,这似乎是 JVM 中的一个错误,需要向 Oracle 报告。因此,我已经向 Oracle 提交了错误报告。当我收到他们的回复时,我会发布更新。

感谢所有尝试过该代码并发现它在您的机器上也崩溃的人。

如果有人有能力/倾向找出编译器中的哪些代码导致了此错误,那么听到这个消息真是太棒了:)

UPDATE:Oracle 的某人昨天回复了,他说他准备了一个修复该 bug 的方法,并要求将我的代码作为回归测试:)他没有解释问题是什么,只是说问题出在 HotSpot JIT 中,但他确实这么做了如果有人感兴趣,请向我发送包含他所做更改的链接:http://cr.openjdk.java.net/~kvn/8046516/webrev/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

未添加本机代码的 Java 致命错误 SIGSEGV 的相关文章

随机推荐

  • 我何时以及为什么应该在 Android 应用程序中使用片段? [复制]

    这个问题在这里已经有答案了 我经常需要应用程序的不同部分拥有自己的特殊行为和 UI 但我不知道片段有何帮助 在大多数情况下 我认为创建 2 个不同的活动 例如 1 个用于平板电脑 1 个用于手机 并在第三类中共享常见行为和事件会更快 那么
  • Java中如何获取unicode字符的十进制值?

    我需要一种编程方式来获取字符串中每个字符的十进制值 以便我可以将它们编码为 HTML 实体 例如 UTF 8 著者名 Decimal 33879 32773 21517 我怀疑您只是对以下内容的转换感兴趣char to int 这是隐式的
  • 如何在 PHP 中不使用 ord() 将字符串转换为 ASCII 值?

    我正在寻找将字符串 Hello world 转换为 php 中的 ASCII 值 但我不想使用ord 是否有其他解决方案可以在不使用的情况下打印 ascii 值ord unpack 根据给定的格式从二进制字符串解包到数组中 Use the
  • PHP cURL multi_exec 请求之间的延迟

    如果我运行标准 cURL multi exec 函数 下面的示例 我会立即获得请求的所有 cURL 句柄 我想在每个请求之间设置 100 毫秒的延迟 有办法做到这一点吗 在 Google 和 StackOverflow 搜索中未找到任何内容
  • 在 VsCode 中激活 Anaconda 环境

    我的系统上有 Anaconda VsCode 也在工作 但是如何让 VsCode 在运行 python 脚本时激活特定环境 只需使用 cmd shift P ctrl shift P for MS Windows Search 选择口译员
  • 使用强化学习解决分类问题[关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 我可以在分类上使用强化学习吗 比如人类活动识别 如何 反馈有两种类型 一是评价性的用于强化学习方法 第二个是有指导意义的用于监督学习 主要用于分类问题 当使用监督学习时 神经网络的权
  • 有没有办法在seaborn点图中设置透明度/alpha级别?

    我想制作一个具有透明度的seaborn点图 以便我可以清楚地看到位于其他不同颜色后面的点 我尝试将 alpha 0 3 添加到对 pointplot 的调用中 并在带有 kind point 的 catplot 中尝试了相同的操作 然而 这
  • 为什么嵌套迭代器闭包不会从外部作用域复制值

    我正在尝试使用嵌套迭代器 其中内部迭代器使用外部迭代器的值 vec 0 10 iter flat map a 0 10 map b a b error a活得不够长 0 10 map b 注意 引用必须对方法调用有效 如果我移动内部闭包 m
  • JQuery Datepicker 不会使用英国日期字符串发布

    如果问题很明显 我深表歉意 但我不明白为什么它突然不起作用 我有一个jquery日期选择器 从我记事起它就一直工作正常 但是突然间 当我尝试提交表单时 日期选择器上的日期选择器重新出现 就好像我提交的日期无效一样 我已经使用以下代码行将日期
  • 自动刷新 IFrame HTML

    如何每 3 秒自动刷新一次 Iframe 而不刷新整个页面 我用但它会显示整个页面刷新 并且每次都会将您带到页面顶部 我的 Iframe 指向一个文本文件来读取我放入的实时消息 有没有一种方法可以做到这一点 而无需刷新整个页面 仅刷新元素
  • 参考:使用 MySQL 扩展的完美代码示例是什么? [关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 这是为了创建一个社区学习资源 我们的目标是提供良好的代码示例 这些代码不会重复复制 粘贴
  • Java继承

    因此 我一直在尝试找到正确的方法来让应该非常简单的继承发挥作用 按照我想要的方式 但我惨败了 考虑一下 class Parent public String name Parent public Parent public void doS
  • ASP.Net Identity 和 IdentityServer4 声明

    我使用 IdentityServer4 作为 OIDC 提供程序和 ASP NET Core 2 0 我已经阅读了几篇文章 以确保 IdentityServer 发出的声明最终出现在 ClaimsPrincipal 即 Auth Cooki
  • 如何查找数组中出现次数最多的项目[重复]

    这个问题在这里已经有答案了 如何找到数组中出现次数最多的项 1 1 1 2 3 mode gt 1 cat dog snake dog mode gt dog 首先构建一个哈希 将数组中的每个值映射到其频率 arr 1 1 1 2 3 fr
  • PyDev 和 Eclipse 未解决的导入问题

    尽管我已经多次使用 Eclipse for Java 但我对 PyDev 和 Python 还很陌生 我正在尝试解决一些 Dive Into Python 示例 这感觉像是一个极其微不足道的问题 但现在却变得非常烦人 我使用的是 Ubunt
  • 使用 method_add 动态覆盖实例方法了解 ruby​​ 元编程

    我有以下来自 Programming Ruby 1 9 的代码 稍作修改 我只是想确保我的思维过程是准确的 module Trace def self included culprit Inject existing methods wit
  • (276/304)*304 的小数舍入关闭

    如果将以下代码放入编译器中 结果会有点奇怪 decimal x 276 304 304 double y 276 304 304 Console WriteLine decimal x x Console WriteLine double
  • Apache 应该服务什么,Tomcat 应该服务什么?

    我正在尝试在 Tomcat 之前设置 Apache Apache 提供什么服务 我知道 Apache 对于静态页面和图像效果更好 我目前在 Tomcat 中部署了一个 war 文件 其中包含静态页面 图像和 Flash 文件 我应该把这些都
  • ASP.NET 托管环境/shadowCopyBinAssemblies

    今天我偶然发现了ShadowCopyBinAssemblies选项中的托管环境 tag 显然这个属性是网络配置 system web 配置布尔选项 指示 Bin 目录中应用程序的程序集是否卷影复制到应用程序的 ASP NET 临时文件目录
  • 未添加本机代码的 Java 致命错误 SIGSEGV

    我从 Java 编译器收到一条我不理解的错误消息 我已经使用 Java 6 和 7 在 OSX 10 6 10 9 和 Ubuntu 14 04 上测试了我的代码 当我使用 Eclipse 调试器或解释器 使用 Xint 选项 运行时 一切