linux运行igv报错,IGV 哐当就不能用了,除了换台电脑还能怎么办?

153049961_1_20190127090759399不知道哪一次更新,也不知道因为更新了什么,PC 上的 IGV 突然就不能用了。除了换一台 Mac 以外还能怎么办。下文记录了 debug 的过程以及一点思考。

前奏

IGV 这个工具因为是 Java 全平台适配的,一般不太容易出现 bug。在 Windows 上常见的问题是由于 Java 32位和64位版本问题造成的。在 64 位的电脑上安装了 32 位的 Java(通常默认就是32位)后,如果给 IGV 分配的内存超过了 2G,就会报内存错误,直接体现为 igb.bat 点击后无法打开。最直接的方法就是把 Java 升级到64位。

然而,不知道是哪一次更新,不知道是因为更新了什么,我的 bug 表现是 IGV 可以正常启动但启动后只要进行任意的一次点击就会闪退。最初我的猜测是因为某一个内容的更新,导致了Java,Windows 和 IGV 三者不兼容。于是我分别更新了最新版的 IGV 和最新版的 Java,然后还升级过一次电脑系统,问题都没有得到解决。当时时间有限,debug 的最直接方式就是绕开 bug。

替代方案

必须要用的软件突然不能用了又急着用,立刻买个 Mac 就可以避免 Windows 上的问题,虽然钱不是问题,但问题是没钱,所以只能寻找其它替代方案。因为 Java 本身是全平台通用的,所以在服务器上下载了 IGV linux 版本,然后通过 Xming 在本地电脑上调用 Linux 开启的 IGV 图形操作界面。

这个方法解决了燃眉之急,但是从服务器通过 Xming 在本地进行点选,很多操作会用明显的卡顿和延迟而且分辨率很低。并非长久之计。

dubug 过程

首先需要看一下相关 IGV 报错信息

A fatal error has been detectedbytheJavaRuntimeEnvironment:

EXCEPTION_ACCESS_VIOLATION(0xc0000005)at pc=0x00007ffe51899e54,pid=8364,tid=0x0000000000004590

JRE version:Java(TM)SERuntimeEnvironment(8.0_191-b12)(build1.8.0_191-b12)

JavaVM:JavaHotSpot(TM)64-BitServerVM(25.191-b12 mixed mode windows-amd64 compressed oops)

Problematicframe:

C[atig6pxx.dll+0x9e54]

Failedto write coredump.Minidumpsarenotenabledbydefaulton client versions ofWindows

Ifyou would like to submit a bug report,please visit:

http://bugreport.Java.com/bugreport/crash.jsp

Thecrash happened outside theJavaVirtualMachineinnativecode.

Seeproblematic frameforwhereto report the bug.

阅读报错信息

因为我本身不懂 Java,只能根据报错提取自己认为关键的内容进行检索。

从以往的经验来看,首先要重点关注哪里失败或者不能启动。在 log 文件 header 部分恰好出现了一句话「Failed to write core dump. Minidumps are not enabled by default on client versions of Windows」,这个信息看起来非常关键,很可能是因为 Windows 不可以写入 core dump 导致的问题,那么自然应该首先开启 core dump 试试。

在 SO 上查到了 core dump 的开启方式,对于Java 8 使用 -XX:+CreateMinidumpOnCrash 参数即可。修改 igv.bat 文件再命令行里添加该参数后重新运行,问题依旧存在,只不过这次除了会生成 log 文件以外,还会生成一个大小几 G 的 core dump 文件。看来这个问题并不是 IGV 闪退的原因。

在检索的过程中,有中文帖记录出现这样的问题是因为「JRE version 和 JDK 不一样」。所以重新下载一个版本对应的 JDK 或者 JRE 就可以解决。虽然我一开始其实也分不清他来有什么区别,也不确定自己是不是同时装了这两个东西,但是抱着试试又不会挂的心态,还是再一次卸载了电脑里的Java。

因为担心是之前 Java 升级有问题,我还专门下载了官方的Java 卸载工具,想把自己电脑里所有和 Java 相关的东西都卸载个干干净净,重新来过。

按照 IGV 网站上给的 Java 8 下载链接,我又一次重新安装了 Java,运行之后真的还没有出现闪退的情况,因为根本就打不开了。其实这就是上文提到的因为 IGV 网站上的 Java 下载链接引导我下载了 32 位 Java 版本,但是 IGV.bat 中使用的内存配置是4G,超过了限额地缘故。我又不得不再一次卸载 32 位重新安装了 64 位Java,闪退问题依旧存在。

不过,至此我确认了电脑不存在所谓的「JRE和JDK版本不一致的问题」,版本信息如下:

# JRE version: Java(TM) SE Runtime Environment (8.0_191-b12) (build 1.8.0_191-b12)

# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.191-b12 mixed mode windows-amd64 compressed oops)

控制变量

Debug 一个非常重要的经验是需要 控制变量。如果有条件,不妨找一台能够正确运行某个程序的机器,看看它和自己报错的机器有什么差别。

为此,我分别查看其他人几台可以正确运行 IGV 的 PC,发现有人的IGV版本较低,有人的 Java 版本较低,但是大家都可以正常使用,于是我又分别测试了几个低版本的 Java 或者 IGV,然并卵。考虑自己的笔记本系统和软件版本与我的工作 PC 高度一致,又用最新版的 IGV 和 Java 8 在笔记本上进行了测试,神奇的是在笔记本却可以正常运行。

至此,我基本懵逼。因为Windows 系统和 IGV 版本以及 Java 版本完全一致的情况下,笔记本可以正常运行IGV,但是 PC 却不可以。这里面一定有某些不可告人的力量。

理解报错信息

通过上面几步折腾,问题的关键应该不在于解决 「Failed to write core dump」而是需要再向前回溯,这个时候就要理解 Java 生成的log文件究竟传达了哪些信息。

通常只有严重的错误引起Java进程非正常退出,出现了Crash,才会产生一个文件名为err+pid number 的日志文件。

检索后发现很多 Java 的报错都会出现 EXCEPTION_ACCESS_VIOLATION(0xc0000005)这一句话,他意味着Java 应用 Crash 时正在运行 JVM 自己的代码,而不是外部的 Java 代码。在这个位置还可能出现 SIGSEGV(0xb)或者 EXCEPTION_STACK_OVERFLOW这样的内容。

再往下看另一个重要信息点是

Problematicframe:

C[atig6pxx.dll+0x9e54]

这里的信息是显示 Crash 时 JVM 正在从哪个库文件执行代码。我遇到问题是 C,还可能是 V 和 J 等等。他们的意思如下

FrameTypeDescription:

C:NativeC frame

j:InterpretedJavaframe

V:VMframe

v:VMgeneratedstub frame

J:Otherframe types,including compiledJavaframes

接下来我又阅读了一下 Java 的 debug 指南,里面的分析思路都是要看 C 后面提示了什么信息,然后给了一些 debug 的建议:The first step to solving a crash in a native library is to investigate the source of the native library where the crash occurred.If the native library is provided by your application, then investigate the source code of your native library. A significant number of issues with JNI code can be identified by running the application with the -Xcheck:jni option added to the command line. See The -Xcheck:jni Option.

If the native library has been provided by another vendor and is used by your application, then file a bug report against this third-party application and provide the fatal error log information.

If the native library where the crash occurred is part of the Java Runtime Environment (JRE) (for example awt.dll, net.dll, and so forth), then it is possible that you have encountered a library or API bug. If so, gather as much data as possible and submit a bug or report, indicating the library name. You can find JRE libraries in the jre/lib or jre/bin directories of the JRE distribution. See Submit a Bug Report.

仔细阅读之后发现基本没读出啥东西,但是现在从报错信息中我已经明确了问题应该指向 atig6pxx.dll。

指果所因

既然定位到了atig6pxx.dll ,就要查查它是什么,搜索 atig6pxx.dll windows10在前面几条结果中,我看到了这样几个信息AMD Graphics Driver not working/incompatible with Win 10 Technical Preview

OpenGl for crimson drivers

153049961_2_20190127090759540

如此看来,这个 atig6pxx.dll 和AMD 的显卡驱动有关,而我的两个显示器之一显卡确实是AMD的,从查询结果来看,AMD 显卡驱动的这个 atig6pxx.dll 和某些 win10 版本搭配在一起就存在问题(我用的就是有问题的版本?)。

接下来再试试 atig6pxx.dllJava的搜索结果,真还搜到了相关的一个帖子,官方给的回复大意是要发帖子的人详细确定显卡和升级之类的各种信息,看来这个问题确实是 Java 和 PC 的显卡驱动有 bug。同时又联想到我的控制变量实验,笔记本是NVIDIA显卡而不是AMD,进一步相信问题可能真出自 AMD 显卡上。

解决问题

确定了bug的原因,接下来就要考虑如何解决问题。

首先需要知道 Java 和显卡驱动是怎么能联系到一起的,检索一下 Javagraphics找到了 官网的一些说明。 这里主要涉及 Java 2D 这么一个东西,在搜索的过程中又找到了 Java 2D 的一些选项。在检索的过程中,还从 SO 看到了一个稍微相关的帖子,其中一个建议也是对显卡进行一系列的测试,其中提到了参数 -Dsun.Java2d.d3d=false。这里的参数和Java 2D 的参数吻合而且有一点眼熟,看到这里就要回过头重新看看 igv.bat 文件。

官方提供的 igv.bat 实际命令如下

::Getthe current batch file's short path

for %%x in (%0) do set BatchPath=%%~dpsx

for %%x in (%BatchPath%) do set BatchPath=%%~dpsx

Java -Xmx4g -Dproduction=true -DJava.net.preferIPv4Stack=true -Dsun.Java2d.noddraw=true -jar %BatchPath%\lib\IGV.jar  %*

仔细看一下,官方这条命令实际调用的程序来自 lib 目录的 igv.jar,只不过添加了几个平时自己根本不会在意的参数,其中 -Dsun.Java2d.noddraw=true和之前 SO 中建议添加的参数非常类似,而这个参数又是一个和显示性能相关的参数。隐约感觉问题就出在这里。

继续贯彻控制变量的思想,首先不加任何参数在 lib 目录下直接运行 igv.jar,嗯,真的没有闪退。回到 bat 依次修改上面三个参数进行测试,直到我把 -Dsun.Java2d.noddraw=true 改为 false 后,bug 消失,至此问题解决。

复盘与反思

综上,通过学习 log 文件,查找关键内容,控制变量测试,一步一步把 Java 的运行错误和显卡联系起来。不过我是万万没想到这错误竟然是和显卡相关。

进一步了解下Dsun.Java2d.noddraw这个参数的作用The following list describes some useful properties on Windows platforms.The DirectDraw/GDI pipeline is the default pipeline for Windows. Change this default as follows:

-Dsun.Java2d.noddraw=true Disable the use of DirectDraw pipeline. GDI will be used instead.

-Dsun.Java2d.noddraw=false Enable the use of DirectDraw pipeline.

-Dsun.Java2d.d3d=false Disable the use of Direct3D pipeline.

也就是说,因为AMD 显卡驱动中 atig6pxx.dll的问题,我目前的电脑并不能只使用 GDI 来进行渲染,而是必须要开启 DirectDraw。至于更深次的原因暂时没有深究的必要。

回顾整个 debug 的过程,虽然一直在尝试使用控制变量的思路,但是具体的测试顺序不对。

使用别人的电脑来控制变量,不相关的因素太多,各种软件版本的不一致只是表象,并没有指明到是真正的显卡差别;而使用自己的笔记本和台式机做比较,才排除了软件版本的关系。

最后进行的控测试才是变量最可控的,应该首先就进行的在同一个电脑上对同样的软件进行不同的操作。其中一个操作是官方并不推荐的直接运行 lib 中的 igv.jar 程序,另一个操作是运行官方推荐的添加了参数的 igv.bat 。如果把这个测试提到第一步来做,就会节省大量的测试时间。

最后,对于 debug 的思考:仔细阅读报错信息确定关键词

成熟的工具一定有着非常详细的报错信息,而我们要做的是从详细的报错信息中提炼关键词进行检索

按照从小到大的顺序尽量找到可以正确运行的方式

想要找到问题所在很关键的一点知道谁或者在哪里可以成功。这一步对之后的 debug 过程十分重要。

所谓从小到大的意思是正确运行和错误运行之间的差异从小到大。最好可以在一台电脑上完成,只是改变运行方式或者参数;如果不行就找配置尽量类似的电脑或服务器进行测试,以此类推。如果我首先能想到抛弃官方的建议打开方式去运行 jar 程序,直接就可以锁定参数问题。

控制变量是进行测试应该遵循的首要思路

通过检索,我们可以找到大量的相关信息,可能会存在各种五花八门的解决方法。如何判断哪些值得尝试哪些不值得尝试非常重要。对于本文的 bug,即便检索到了很多关于软件版本的问题,只要我在版本相同的另一台电脑运行成功,那么所有和 Java 版本,Windows 版本以及 IGV 版本相关的内容都可以忽略掉,就省去了多次卸载安装这样的无用功。同时根据检索信息再结合控制变量的思想就更加容易锁定问题,进而找到解决方式。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 允许您玩在线游戏,与世界各地的人聊天,计算您的按揭利息,并以 3D 形式查看图像。这些以 Java 编程语言编写的应用程序和可从浏览中访问的应用程序称为小程序。公司还将 Java 小程序用于内部网应用程序和其他电子商务的解决方案。所有主要行业的公司都在使用 Java。无论是部署在手机、嵌入式设备、游戏机、笔记本电脑还是数据中心,Java 都提供了当今网络应用所需要的丰富的用户界面、性能、多功能性、可移植性和安全性。Java 平台标准版软件是快速开发和部署安全、便携式应用程序的首选平台,可跨大多数操作系统的服务器和桌面系统。 Java 平台标准版(Java SE)可让您在台式机和服务器以及当今苛刻的嵌入式环境中开发和部署 Java 应用程序。Java 提供了当今应用程序所需的丰富的用户界面、性能、通用性、可移植性和安全性。 Java SE Runtime Environment(运行时环境)包含了运行以 Java 编程语言编写的程序所必需的 Java 虚拟机、运行时类库和 Java 应用程序启动器。 Java 平台的安全性 一个由角色提供的安全信息的描述。适用于开发人员,系统管理员,家庭用户和安全专业人士。 主要特点: - 在一个平台上编写软件,并可在几乎任何其它平台上运行 - 创建的程序可在 Web 浏览器和 Web 服务中运行 - 可开发用于在线论坛、商店、投票、HTML 表单处理等服务器端应用程序 - 结合基于 Java 技术的应用程序或服务来创建高度可定制的应用程序或服务 - 为手机、远程处理器、低成本消费产品和几乎任何具有数字内核的设备编写功能强大且高效的应用程序 Java SE 8 现在可用 Java 平台标准版 8(Java SE 8)是一个主要的功能版本。它包含了很多功能领域的新功能和增强功能。Java SE 8 通过减少样板代码,改进了集合和注释,简单的并行编程模型和更有效地利用现代多核处理器,提高了开发人员的工作效率和显着的增强了应用程序的性能。 Java SE 8u172 版本更新:2018年4月17日

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值