Java VM:1.6.0_17 和 1.6.0_18 上的可重现 SIGSEGV,如何报告?

Posted

技术标签:

【中文标题】Java VM:1.6.0_17 和 1.6.0_18 上的可重现 SIGSEGV,如何报告?【英文标题】:Java VM: reproducible SIGSEGV on both 1.6.0_17 and 1.6.0_18, how to report? 【发布时间】:2011-01-18 22:43:03 【问题描述】:

编辑:这个可重现的 SIGSEGV 发生在具有多个 proc 和超过 2GB 内存的 Linux 机器上,因此 Java 默认为 -server 模式。有趣的是,如果我强制“-client”,就不会再出现崩溃了......(我仍然不太确定如何处理我的可重现 SIGSEGV,但它仍然很有趣)。

首先请注意,这与以下内容有点相关但并不完全相同,因为在我们的例子中,它只是发生了一个 SIGSEGV,我们可以可靠地触发它:

JVM OutOfMemory error "death spiral" (not memory leak)

这是相关的,因为当我们向应用程序提供“大量数据”时就会发生这种情况:数据来自文本文件,然后经过数字处理(是的,Java 中的财务数字处理)。

我可以仅使用有效的 Java 代码可靠地触发 JVM 到 SIGSEGV。

注意:我总是会导致 JVM 1.6.0_17 和 JVM 1.6.0_18 崩溃,这个问题不是关于如何解决这个问题(例如使用 VM 参数可能 em> 解决问题,但我不是在那之后,我想知道如何处理这个始终可重现的 SIGSEGV)。

我有一个解决方法,它只是在启动我们的应用程序时使用 Java 1.5(同时仍然使用 Java 1.6 在同一台机器上同时运行 IntelliJ IDEA 等),但我的问题是这是否应该报告与否,如果应该,如何在知道日志本身包含专有信息(完整的 hs_err_..._log)的情况下报告它。

可以排除硬件错误:

这发生在一个正常运行时间通常达到数月的工作站上(我只在发布影响我精简和强化的 Debian Linux 的关键安全补丁时才重新启动它,这确实不经常发生)以及哪些应用程序永不崩溃(使其不太可能是该机器上的硬件问题 [更多内容])

相同的应用程序在相同负载下的 JVM 1.5 下的同一台机器上完美运行(这就是我测试应用程序的方式:我只是在 1.5 的 VM 下启动它)

同一应用程序在相同(巨大)负载下的数百台客户端计算机上运行良好(在 Windows + JVM 1.5 或 1.6 上从未崩溃过一次,在 OS X + JVM 1.5 或 1.6 上从未崩溃过一次 [a崩溃意味着来自客户端的即时电话])

同一台机器上的其他应用程序和相同的 1.6.0_17 或 1.6.0_18 JVM 永远不会崩溃(例如,我有两个 IntelliJ IDEA 实例在同一台机器上作为两个不同的用户运行,但他们没有崩溃)

机器“定期”使用 memtest 进行测试(在安装新操作系统之前,最近一次发生在我安装 Debian Lenny 时,不久前)

这是可按需复制的 SIGSEGV:

... $uname -a
Linux saturn 2.6.26-2-686 #1 SMP Wed Nov 4 20:45:37 UTC 2009 i686 GNU/Linux
... $ export /home/wizard/jdk1.6.0_17/bin:$PATH
... $ java -version
java version "1.6.0_17"
Java(TM) SE Runtime Environment (build 1.6.0_17-b04)
Java HotSpot(TM) Server VM (build 14.3-b01, mixed mode)

启动应用程序,输入“大量数据”,等待几秒钟...

那么,对于 1.6.0_17:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0xb76d0080, pid=30793, tid=2514328464
#
# JRE version: 6.0_17-b04
# Java VM: Java HotSpot(TM) Server VM (14.3-b01 mixed mode linux-x86 )
# Problematic frame:
# V  [libjvm.so+0x4bc080]
#
# An error report file with more information is saved as:
# /home/wizard/hs_err_pid30793.log
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp

(请注意,'[libjvm.so+0x4bc080]' 行在每个 SIGSEGV 上与 1.6.0_17 一致)

或对于 1.6.0_18:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0xb77468f0, pid=722, tid=2514516880
#
# JRE version: 6.0_18-b07
# Java VM: Java HotSpot(TM) Server VM (16.0-b13 mixed mode linux-x86 )
# Problematic frame:
# V  [libjvm.so+0x4d88f0]
#
# An error report file with more information is saved as:
# /home/wizard/hs_err_pid722.log
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#
Aborted

(请注意,“[libjvm.so+0x4d88f0]”这一行在每个 SIGSEGV 上对于 1.6.0_18 都是一致的)

问题是日志文件包含专有信息 无法共享。

重现一个重现问题的“小测试用例”也不现实:它类似于上面链接的问题,只有当“大量数据”被馈送到应用程序时才会发生这种情况。

请注意,完全相同的应用程序,在完全相同的硬件上,具有完全相同的 JVM,但另一个版本的 Linux(我之前有 Debian Etch)不会触发该 SIGSEGV 一次。

但这并不意味着 JVM 没有问题:它仍然可能是 JVM 问题。

我应该举报吗?如何举报? (请记住,编写“可重现的小型测试用例”是一种妄想,并且日志包含不应泄露的专有信息)。我应该只编辑日志并发送吗?

当您的日志包含专有信息并且重现问题的测试用例实际上不可行时,报告此类可重现 SIGSEGV 的程序是什么?

你们有没有人成功打开过这样的错误,然后在随后的 Java 版本中看到它得到解决?

您认为报告这样的问题对“Java 社区”有益还是我不应该打扰,因为它不重要?

【问题讨论】:

这是否仍然适用于最新版本的 Java?还可以考虑使用 IBM Java 或 JRocket。 @Thorbjørn Ravn Andersen:今晚晚些时候我会检查并在这里报告 @Thorbjørn Ravn Andersen:刚刚下载了 JRE 版本:6.0_25-b06。完全相同的崩溃:-/ 另外,这是否发生在官方支持的 Linux 平台之一上? @Thorbjørn Ravn Andersen:如果我有时间我会尝试使用 IBM 的 JRE 和其他发行版... 【参考方案1】:

我在升级到 JDK 1.6_18 时遇到了类似的问题,似乎可以使用以下选项解决:

-server
-Xms256m
-Xmx748m
-XX:MaxPermSize=128m

-verbose:gc
-XX:+PrintGCTimeStamps
-Xloggc:/tmp/gc.log
-XX:+PrintHeapAtGC
-XX:+PrintGCDetails
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath="/tmp"

-XX:+UseParallelGC
-XX:-UseGCOverheadLimit

# Following options just to remote monitoring with jconsole, useful to see JVM behaviour at runtime
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=12345
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=MyHost

我还是没有仔细检查(是生产环境),但我认为错误是由于两个原因:

1) 关于堆和/或永久空间的错误设置(我认为 JDK 1.6 需要比以前的 JVM 版本更多的堆和永久空间)导致 OutOfMemoryError,但是

2) 在错误的原始设置中有人写了

-XX:+HeapDumpOnOutOfMemoryError="/tmp"

而不是

-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath="/tmp"

所以可能 JVM 无法编写 heapdump,我们只得到了 SIGSEGV(以前的版本在工作目录中编写了 heapdump)。

也检查-server -XX:+UseParallelGC -XX:-UseGCOverheadLimit 选项。我认为使用 VM 参数不是一种解决方法,但正确的方法也是因为垃圾收集器(不仅是)在 1.5 和 1.6 之间发生了变化。

【讨论】:

@glenti:+1,很酷,您对 SO 的第一个回答是对我的一个问题 :) 尝试了您建议的所有内容,但它仍然崩溃。没有 OutOfMemoryError 的迹象,我尝试使用自定义 JLabel 显示内存使用情况。显然也没有 PermGen 问题。 @glenti:你的帖子让我思考......我正在使用一台具有多个 proc 和超过 2GB 内存的 Linux 机器,因此 Java 默认为 -server 模式。有趣的是,如果我强制“-client”,就不会再崩溃了......(我仍然不太确定如何处理我的可重现 SIGSEGV,但它仍然很有趣)【参考方案2】:

问题是日志文件 包含专有信息 不能共享。再现“小 重现问题的测试用例” 也不现实

如果您不能向 Sun 提供可重现的测试用例,他们甚至不会看它。即使您确实提供了可用的测试用例,他们也很有可能会忽略它。 Sun 的错误提交过程还有很多不足之处。

我应该报告这个以及如何报告?

如果您无法提出可重现的测试用例,请不要打扰。如果他们无法重现问题,您希望他们怎么做?

请注意,完全相同的应用程序, 在完全相同的硬件上,与 完全相同的 JVM 但另一个 Linux 版本(我有 Debian Etch 以前)没有触发 SIGSEGV 一次。

它是否可以在具有相同硬件和相同 Linux 版本的不同机器上工作?

【讨论】:

我相信购买支持会让您获得更多关注。多少,取决于您购买的级别。 @Kevin: 啊该死的......我可以将我的高清 dd 到另一个,因此尝试使用完全相同的 Linux 内核/配置和 JVM 来查看 SIGSEGV 是否也可重现,但你是什么写在那里很郁闷。一个测试用例意味着要发送数百兆字节的数据。哦,好吧,如果它可以在任何硬件上重现,也许我应该只运送硬盘或制作可以重现问题的可启动 CD :)(我是半认真的)OpenJDK 怎么样?如果我能在 OpenJDK 7 下可靠地重现这一点,情况会有所不同吗? @WizardOfOdds :您说日志文件中有专有信息。您能否编写一个解析器或其他东西来“平庸化”这些数据,然后将您的日志文件发送给 Sun ?【参考方案3】:

如果有帮助,您的崩溃报告中的错误提交链接有以下免责声明:

此外,Sun Microsystems 尊重您对隐私的渴望。从该计划收集的个人数据不会出售、提供或与 Sun 以外的组织共享。我们将使用这些数据与您沟通,以澄清有关您提交的报告和/或该报告状态的问题。您报告的问题可能会提供给其他 JDC 成员或 Sun 客户,但您的个人数据将被保密。如果您对上述条件不满意,请不要按提交按钮。如果您有任何问题,请咨询我们的Privacy Policy。

就个人而言,如果可以通过日志移交有问题的代码段,如果数据不太敏感(也许数据可以在日志中被屏蔽或混淆?),我会报告它。

除非你知道它的真正原因,否则你不可能真正判断这个 bug 对其他人是否“重要”。报告它可能是 Sun 的工程师找出严重问题原因的第一步。

【讨论】:

@matt b:是的,正在考虑清除 hs_err_...日志中的文件名。我会看看 Proguarded 版本是否也会触发崩溃,然后我什至可以发送经过混淆的 .jar + 数据来重现问题。仍然在这个问题上摸不着头脑。【参考方案4】:

你应该问自己的第一个问题是:

我使用的是官方支持的 Linux 发行版吗?

如果没有,请切换到一个。

如果是,请向 Sun 报告!

【讨论】:

@Throbjorn: 官方支持谁?你是说孙?我正在使用有史以来最稳定的 Linux 发行版,很多人讨厌它,因为包含最新的花絮和口哨声和钟声总是很慢,而像我这样的其他人喜欢它,因为它坚如磐石:Debian :) 由生成您正在使用的 JVM 的实体支持。 Sun 没有说他们的 Java 将在现有的任何 Linux 发行版上运行,但他们说他们“支持”java.sun.com/javase/6/webnotes/install/… 上列出的发行版(其中“支持”意味着甚至考虑听取错误报告)。 Debian 不存在,但 Ubuntu 存在。改用它。 @Throbjorn: 哦,好的,我明白你的意思了(也感谢链接)...也就是说 Ubuntu 实际上是基于 Debian 的 :) Debian 是系统管理员最推崇的发行版,并且功能强大在 Real-World [TM] 服务器中,我不会切换到任何其他 Linux 发行版;)也就是说问题不在于 SIGSEGV(因为我有解决方法),而是如何处理它...... :)

以上是关于Java VM:1.6.0_17 和 1.6.0_18 上的可重现 SIGSEGV,如何报告?的主要内容,如果未能解决你的问题,请参考以下文章

Driver.getConnection 使用 SQLServer 驱动程序和 Java 1.6.0_29 挂起

Java 1.6.0_20 中的 Eclipse Node.getTextContent()

CentOS yum 安装历史版本 java

使用 java 版本 1.6.0_37 的 Centos 中的 APNS NetworkIOException SSLHandshake 失败

(个人)CentOS的JDK安装

Eclipse开发环境配置