为什么java应用程序在gdb中崩溃,但在现实生活中正常运行? [英] Why does java app crash in gdb but runs normally in real life?

查看:121
本文介绍了为什么java应用程序在gdb中崩溃,但在现实生活中正常运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

试图从gdb运行java应用程序会导致段错误,但单独运行应用程序却不行。这个应用程序是一个.JAR,它使用 JOGL 和一些内存映射与GPU交谈。



下面的Stacktrace提示某种内存访问问题,但我不明白它为什么在GDB中显示,但不在现实生活中。 gdb需要知道哪些环境因素才能正确执行?



在JVM的OpenJDK 6和7以及Oracle JRE 7之间,此问题依然存在。Oracle JRE在segfault之前运行一段时间才能启动。所有段错误在测试之间的发生和位置方面是一致的。

Segfault在GPU和驱动程序之间持续存在(!!):nvidia,radeon,fglrx current和fglrx beta(14。 XX)。 GDB将成功地附加到我的程序的一个已经运行的实例上,但是gDEBugger似乎不可能这样做,这是最终需要解决的。



没有意图用gdb进行真正的调试。相反,我尝试使用 gDEBugger 执行OpenGL调试。 gDEBugger显然依赖于GDB作为其后端的一部分,所以如果GDB失败,gDEBugger也会失败。这导致尝试单独运行gdb来隔离问题。

  gDEBugger输出:
GDB字符串:[使用libthread_db启用线程调试]
GDB字符串: libthread_db库/lib/x86_64-linux-gnu/libthread_db.so.1。
线程已创建:140737353893632(LWP:3265)
线程已创建:140737294624512(LWP:3266)
线程已创建:140737293571840(LWP:3267)
线程创建时间:140737292519168(LWP: (LWP:3269)
线程已创建:140737155180288(LWP:3269)
线程已创建:140737154127616(LWP:3270)
线程已创建:140736913602304(LWP:3271)
线程已创建:140736909629184 LWP:3272)
创建的主题:140736908576512(LWP:3273)
创建时间:140736907523840(LWP:3274)
创建时间:140736906471168(LWP:3275) 140736905418496(LWP:3276)
创建线程:140736278275840(LWP:3277)
线程创建时间:140736272963328(LWP:3278)
线程创建时间:140736271910656(LWP:3279)创建时间:140736270857984(LWP:3280)
创建线索:140736269805312(LWP:3281)
线程创建时间:140737287657216(LWP:3285)
线程创建时间:140736261945088(LWP:3289)
GDB字符串:[线程0x7fffb6e67700(LWP 3289)退出]
Th已创建:140736261945088(LWP:3290)
API连接建立:gDEBugger服务器管理器
b $ b API连接建立:gDEBugger OpenGL服务器
GDB字符串:[线程0x7fffb77e8700(LWP 3279)退出]
GDB字符串:[线程0x7fffb76e7700(LWP 3280)退出]
调试字符串:gDEBugger OpenGL Server初始化
创建线程:140736270857984(LWP:3292)
线程创建时间:140735692441344(LWP:3294)
线程创建时间:140735582430976(LWP:3295)
线程创建时间:
OpenGL渲染上下文1创建
信号:SIGSEGV
处理退出


$ java -versionjava version1.6.0_33
OpenJDK运行时环境(IcedTea6 1.13.5)(6b33-1.13.5-1ubuntu0.14.04)
OpenJDK 64位服务器虚拟机(版本23.25-b01,混合模式)

$ gdb -version
GNU gdb(Ubuntu 7.7.1-0ubuntu5〜14.04.2)7.7.1

$ cat / etc / lsb-release
DISTRIB_ID = Ubuntu
DISTRIB_RELEASE = 14.04
DISTRIB_CODENAME =可信$ b $ DISTRIB_DESCRIPTION =Ubuntu 14.04.1 LTS

$ fglrxinfo
display::0.0 screen:0
OpenGL供应商字符串:Advanced Micro Devices,Inc.
OpenGL渲染字符串:AMD Radeon HD 5570
OpenGL版本字符串:4.4.12967兼容性配置文件上下文14.20


$ gdb --args java -jar RunMe.jar
GNU gdb(Ubuntu 7.7.1-0ubuntu5〜14.04.2) 7.7.1
版权所有(C)2014自由软件基金会,Inc.
许可证GPLv3 +:GNU GPL版本3或更高版本< http://gnu.org/licenses/gpl.html>
这是免费软件:您可以自由更改和重新分配它。
在法律允许的范围内,不存在任何担保。有关详细信息,请键入显示复制
和显示保修。
这个GDB被配置为x86_64-linux-gnu。
输入显示配置以获取配置详细信息。
有关错误报告的说明,请参阅:
< http://www.gnu.org/software/gdb/bugs/> ;.
在线查找GDB手册和其他文档资源:
< http://www.gnu.org/software/gdb/documentation/> ;.
如需帮助,请输入help。
键入apropos word以搜索与word相关的命令...
从java中读取符号...从/ usr / lib / debug中读取符号// usr / lib / jvm / java -6- OpenJDK的,AMD64 / JRE /斌/ java的...来完成。
完成。
(gdb)显示配置
这个GDB配置如下:
configure --host = x86_64-linux-gnu --target = x86_64-linux-gnu
--with -auto-load-dir = $ debugdir:$ datadir / auto-load
--with-auto-load-safe-path = $ debugdir:$ datadir / auto-load
--with-expat
--with-gdb-datadir = / usr / share / gdb(relocatable)
--with-jit-reader-dir = / usr / lib / gdb(可重定位)
- without-libunwind-ia64
--with-lzma
--with-python = / usr(relocatable)
--with-separate-debug-dir = / usr / lib / debug(可重新定位)
--with-system-gdbinit = / etc / gdb / gdbinit
--with-zlib
--without-babeltrace
(gdb)运行
启动程序:/ usr / bin / java -jar RunMe.jar
[使用libthread_db启用线程调试]
使用主机libthread_db库/lib/x86_64-linux-gnu/libthread_db.so.1。
进程6866执行新程序:
使用主机libthread_db库执行新程序:/ usr / lib / jvm / java-6 -openjdk-amd64 / jre / bin / java
[使用libthread_db启用线程调试] /lib/x86_64-linux-gnu/libthread_db.so.1。
[新线程0x7ffff7fc4700(LWP 6870)]
[新线程0x7ffff486c700(LWP 6871)]
[新线程0x7ffff476b700(LWP 6872)]
[新线程0x7ffff466a700(LWP 6873) )]
[新线程0x7fffea2d6700(LWP 6874)]
[新线程0x7fffea1d5700(LWP 6875)]
[新线程0x7fffea0d4700(LWP 6876)]
[新线程0x7fffe9d0a700 LWP 6877)]
[新线程0x7fffe9c09700(LWP 6878)]
[新线程0x7fffe9b08700(LWP 6879)]
[新线程0x7fffe9a07700(LWP 6880)]
[New Thread 0x7fffe9906700(LWP 6881)]
...
[新线程0x7fffe8110700(LWP 6882)]
[新线程0x7fffe3169700(LWP 6883)]
[新线程0x7fffe3068700(LWP 6884) )]
[新线程0x7fffe2f67700(LWP 6885)]
[新线程0x7fffe2e66700(LWP 6886)]
[新线程0x7fffe2d65700(LWP 6887)]
[线程0x7fffe2d65700(LWP
[新线程0x7fffe2d65700(LWP 6895)]
[线程0x7fffe2d65700(LWP 6891)退出]
[新线程0x7fffe2d65700(LWP 6895)]
[线程0x7f
[新线程0x7fffe2d65700(LWP 6896)]
[新线程0x7fffe0efd700(LWP 6897)]
libEGL警告:DRI2:未能认证
[新线程0x7fffe2d65700(LWP 6896)新线程0x7fff9799f700(LWP 6898)]
[新线程0x7fff9719e700(LWP 6899)]
[新线程0x7fff9699d700(LWP 6900)]
[线程0x7fffe2d65700(LWP 6896)退出]
[新线程0x7fffe2d65700(LWP 6901)]
[新线程0x7fffe01ab700(LWP 6902)]
[新线程0x7fff92f00700(LWP 6903)]
[新线程0x7fff92dff700(LWP 6904)]
[新线程0x7fff92cfe700(LWP 6905)]
设置音响系统... [新线程0x7fff92bfd700(LWP 6906)]

[新线程0x7fff92afc700(LWP 6907)]
[新线程0x7fff929fb700(LWP 6908)]
[新线程0x7fff928fa700(LWP 6909)]
[新线程0x7fff927f9700(LWP 6910)]
[新线程0x7fff926f8700(LWP 6911) ]
[新线程0x7fff925f7700(LWP 6912)]

编程接收到的信号SIGSEGV,分段错误。
[切换到线程0x7fffe2f67700(LWP 6885)]
0x00007ffff6b3a770 in acl_CopyRight()
from / usr / lib / jvm / java-6 -openjdk-amd64 / jre / lib / amd64 / server /libjvm.so
(gdb)
#0 0x00007ffff6b3a770 in acl_CopyRight()
from / usr / lib / jvm / java-6 -openjdk-amd64 / jre / lib / amd64 / server unsafe_CopyMemory2(env =< optim out>,
unsafe =<优化出>,srcObj = 0x0,srcOffset = 140737008618496,dstObj = 0x0,
)/libjvm.so
#1 0x00007ffff6d51309 dstOffset = 140737006779392,size = 1024)
在/build/buildd/openjdk-6-6b33-1.13.5/build/openjdk/hotspot/src/share/vm/prims/unsafe.cpp:689
#2 0x00007fffed011790在? ()
#3 0x0000000000000400在?? ()
#4 0x0000000000000000 in ?? ()
警告:当前语言与此框架不匹配。
(gdb)quit
调试会话处于活动状态。

劣等1 [过程6866]将被杀死。

无论如何退出? (y或n)y

更新:切换到AMD CodeXL

解决方案


为什么java应用程序在gdb中崩溃,但在现实生活中正常运行?

因为它实际上不是 崩溃。 / p>

Java使用投机加载。如果指针指向可寻址内存,则加载成功。很少指针指向可寻址内存,并且尝试的加载生成 SIGSEGV ...这些java运行时截获,使内存重新寻址,并重新启动加载指令。 / b>

在调试java程序时,通常需要这样做:

  (gdb)句柄SIGSEGV nostop noprint pass 

不幸的是,如果涉及到一些JNI代码,并且 代码 SIGSEGV s,GDB会高兴地忽略该信号,导致劣化(被调试)进程死亡。对于后一个问题,我还没有找到可以接受的解决方案。


Attempting to run java app from gdb results in segfault, yet running app alone does not. This app is a .JAR which uses JOGL and a bit of memory-mapping to talk to the GPU.

Stacktrace below hints at some sort of memory access problem but I don't understand why it manifests in GDB but not in real life. Could there be some environment factor gdb needs to know to allow proper execution?

This issue persists between JVMs OpenJDK 6 and 7, as well as Oracle JRE 7. The oracle JRE runs a little farther into startup before segfault. All segfaults are otherwise consistent in occurrence and location between trials.

Segfault persists between GPUs and drivers(!!): nvidia, radeon, fglrx current and fglrx beta (14.xx). GDB will successfully attach to an already-running instance of my program, however it doesn't seem possible for gDEBugger to do this, which is ultimately what needs to work.

There is no intent to actually debug with gdb. Rather I am trying to use gDEBugger to perform OpenGL debugging. gDEBugger apparently relies on GDB as part of its backend, so if GDB fails, so does gDEBugger. This resulted in attempts to run gdb alone to isolate the issue.

gDEBugger output:
GDB String:  [Thread debugging using libthread_db enabled]  
GDB String:  Using host libthread_db library  /lib/x86_64-linux-gnu/libthread_db.so.1 .  
Thread Created: 140737353893632 (LWP: 3265)
Thread Created: 140737294624512 (LWP: 3266)
Thread Created: 140737293571840 (LWP: 3267)
Thread Created: 140737292519168 (LWP: 3268)
Thread Created: 140737155180288 (LWP: 3269)
Thread Created: 140737154127616 (LWP: 3270)
Thread Created: 140736913602304 (LWP: 3271)
Thread Created: 140736909629184 (LWP: 3272)
Thread Created: 140736908576512 (LWP: 3273)
Thread Created: 140736907523840 (LWP: 3274)
Thread Created: 140736906471168 (LWP: 3275)
Thread Created: 140736905418496 (LWP: 3276)
Thread Created: 140736278275840 (LWP: 3277)
Thread Created: 140736272963328 (LWP: 3278)
Thread Created: 140736271910656 (LWP: 3279)
Thread Created: 140736270857984 (LWP: 3280)
Thread Created: 140736269805312 (LWP: 3281)
Thread Created: 140737287657216 (LWP: 3285)
Thread Created: 140736261945088 (LWP: 3289)
GDB String:  [Thread 0x7fffb6e67700 (LWP 3289) exited]  
Thread Created: 140736261945088 (LWP: 3290)
API Connection Established: gDEBugger Servers Manager
Thread Created: 140736234641152 (LWP: 3291)
GDB String:  [Thread 0x7fffb6e67700 (LWP 3290) exited]  
API Connection Established: gDEBugger OpenGL Server
GDB String:  [Thread 0x7fffb77e8700 (LWP 3279) exited]  
GDB String:  [Thread 0x7fffb76e7700 (LWP 3280) exited]  
Debug String: gDEBugger OpenGL Server was initialized
Thread Created: 140736270857984 (LWP: 3292)
Thread Created: 140735692441344 (LWP: 3294)
Thread Created: 140735582430976 (LWP: 3295)
Thread Created: 140735574038272 (LWP: 3296)
OpenGL Render Context 1 Created
Signal: SIGSEGV
Process Exit


$ java -versionjava version "1.6.0_33"
OpenJDK Runtime Environment (IcedTea6 1.13.5) (6b33-1.13.5-1ubuntu0.14.04)
OpenJDK 64-Bit Server VM (build 23.25-b01, mixed mode)

$ gdb -version
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1

$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.1 LTS"

$ fglrxinfo
display: :0.0  screen: 0
OpenGL vendor string: Advanced Micro Devices, Inc.
OpenGL renderer string: AMD Radeon HD 5570     
OpenGL version string: 4.4.12967 Compatibility Profile Context 14.20


$ gdb --args java -jar RunMe.jar
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from java...Reading symbols from /usr/lib/debug//usr/lib/jvm/java-6-openjdk-amd64/jre/bin/java...done.
done.
(gdb) show configuration
This GDB was configured as follows:
   configure --host=x86_64-linux-gnu --target=x86_64-linux-gnu
             --with-auto-load-dir=$debugdir:$datadir/auto-load
             --with-auto-load-safe-path=$debugdir:$datadir/auto-load
             --with-expat
             --with-gdb-datadir=/usr/share/gdb (relocatable)
             --with-jit-reader-dir=/usr/lib/gdb (relocatable)
             --without-libunwind-ia64
             --with-lzma
             --with-python=/usr (relocatable)
             --with-separate-debug-dir=/usr/lib/debug (relocatable)
             --with-system-gdbinit=/etc/gdb/gdbinit
             --with-zlib
             --without-babeltrace
(gdb) run
Starting program: /usr/bin/java -jar RunMe.jar
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
process 6866 is executing new program: /usr/lib/jvm/java-6-openjdk-amd64/jre/bin/java
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff7fc4700 (LWP 6870)]
[New Thread 0x7ffff486c700 (LWP 6871)]
[New Thread 0x7ffff476b700 (LWP 6872)]
[New Thread 0x7ffff466a700 (LWP 6873)]
[New Thread 0x7fffea2d6700 (LWP 6874)]
[New Thread 0x7fffea1d5700 (LWP 6875)]
[New Thread 0x7fffea0d4700 (LWP 6876)]
[New Thread 0x7fffe9d0a700 (LWP 6877)]
[New Thread 0x7fffe9c09700 (LWP 6878)]
[New Thread 0x7fffe9b08700 (LWP 6879)]
[New Thread 0x7fffe9a07700 (LWP 6880)]
[New Thread 0x7fffe9906700 (LWP 6881)]
...
[New Thread 0x7fffe8110700 (LWP 6882)]
[New Thread 0x7fffe3169700 (LWP 6883)]
[New Thread 0x7fffe3068700 (LWP 6884)]
[New Thread 0x7fffe2f67700 (LWP 6885)]
[New Thread 0x7fffe2e66700 (LWP 6886)]
[New Thread 0x7fffe2d65700 (LWP 6887)]
[Thread 0x7fffe2d65700 (LWP 6887) exited]
[New Thread 0x7fffe2d65700 (LWP 6891)]
[Thread 0x7fffe2d65700 (LWP 6891) exited]
[New Thread 0x7fffe2d65700 (LWP 6895)]
[Thread 0x7fffe2d65700 (LWP 6895) exited]
[New Thread 0x7fffe2d65700 (LWP 6896)]
[New Thread 0x7fffe0efd700 (LWP 6897)]
libEGL warning: DRI2: failed to authenticate
[New Thread 0x7fff9799f700 (LWP 6898)]
[New Thread 0x7fff9719e700 (LWP 6899)]
[New Thread 0x7fff9699d700 (LWP 6900)]
[Thread 0x7fffe2d65700 (LWP 6896) exited]
[New Thread 0x7fffe2d65700 (LWP 6901)]
[New Thread 0x7fffe01ab700 (LWP 6902)]
[New Thread 0x7fff92f00700 (LWP 6903)]
[New Thread 0x7fff92dff700 (LWP 6904)]
[New Thread 0x7fff92cfe700 (LWP 6905)]
Setting up sound system...[New Thread 0x7fff92bfd700 (LWP 6906)]

[New Thread 0x7fff92afc700 (LWP 6907)]
[New Thread 0x7fff929fb700 (LWP 6908)]
[New Thread 0x7fff928fa700 (LWP 6909)]
[New Thread 0x7fff927f9700 (LWP 6910)]
[New Thread 0x7fff926f8700 (LWP 6911)]
[New Thread 0x7fff925f7700 (LWP 6912)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffe2f67700 (LWP 6885)]
0x00007ffff6b3a770 in acl_CopyRight ()
   from /usr/lib/jvm/java-6-openjdk-amd64/jre/lib/amd64/server/libjvm.so
(gdb) where
#0  0x00007ffff6b3a770 in acl_CopyRight ()
   from /usr/lib/jvm/java-6-openjdk-amd64/jre/lib/amd64/server/libjvm.so
#1  0x00007ffff6d51309 in Unsafe_CopyMemory2 (env=<optimized out>, 
    unsafe=<optimized out>, srcObj=0x0, srcOffset=140737008618496, dstObj=0x0, 
    dstOffset=140737006779392, size=1024)
    at /build/buildd/openjdk-6-6b33-1.13.5/build/openjdk/hotspot/src/share/vm/prims/unsafe.cpp:689
#2  0x00007fffed011790 in ?? ()
#3  0x0000000000000400 in ?? ()
#4  0x0000000000000000 in ?? ()
Warning: the current language does not match this frame.
(gdb) quit
A debugging session is active.

    Inferior 1 [process 6866] will be killed.

Quit anyway? (y or n) y

UPDATE: Switched to AMD CodeXL (basically the most recent form of gDEBugger) and situation hasn't changed much.

解决方案

Why does java app crash in gdb but runs normally in real life?

Because it doesn't actually crash.

Java uses speculative loads. If a pointer points to addressable memory, the load succeeds. Rarely the pointer does not point to addressable memory, and the attempted load generates SIGSEGV ... which java runtime intercepts, makes the memory addressable again, and restarts the load instruction.

When debugging java programs, one has to generally do this:

(gdb) handle SIGSEGV nostop noprint pass

Unfortunately, if there is some JNI code involved, and that code SIGSEGVs, GDB will happily ignore that signal as well, resulting in the death of inferior (being debugged) process. I have not found an acceptable solution for that latter problem.

这篇关于为什么java应用程序在gdb中崩溃,但在现实生活中正常运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆