18

我们最近发生了一次 JVM 崩溃,留下了一个由 gcore 命令生成的核心转储文件。我们想查看文件的内容并找出导致崩溃的确切原因。

使用该jmap命令,您应该能够将核心转储文件转换为 hprof 文件格式的文件,然后您可以使用 VisualVM 和许多其他工具对其进行分析。我试过这个并收到一条错误消息。这是我运行的命令(在发生崩溃的同一个盒子上,使用相同的 JVM):

jmap -dump:format=b,file=dump.hprof /usr/java/jdk1.6.0_16/bin/java core.dump.2878

整个回应是:

> Attaching to core core.dump.8483 from executable /usr/java/jdk1.6.0_16/bin/java, please wait...
> Error attaching to core file: Can't attach to the core file

这不是一个非常有用的错误消息。我想知道这是否是权限问题,但运行该命令的消息与运行导致核心转储的 JVM 的相同使用相同。我也想知道核心文件是否损坏,所以我决定使用gdb看看我是否可以打开核心文件,看看里面有什么。这就是我得到的:

> 数据库
GNU gdb (GDB) 红帽企业 Linux (7.0.1-37.el5_7.1)
许可 GPLv3+:GNU GPL 版本 3 或更高版本
这是免费软件:您可以自由更改和重新分发它。
在法律允许的范围内,不提供任何保证。输入“显示复制”
和“显示保修”了解详情。
这个 GDB 被配置为“x86_64-redhat-linux-gnu”。
有关错误报告说明,请参阅:
<http://www.gnu.org/software/gdb/bugs/>。
(gdb) 核心文件 core.dump.8483
[新线程2889]
[新线程2893]
[新线程2894]
[新线程2895]
[新线程2896]
[新线程2904]
[新线程2915]
[新线程2916]
[新线程2917]
[新线程2921]
[新线程2922]
[新线程3175]
[新线程3239]
[新线程3252]
[新线程3258]
【新线程3260】
[新线程3356]
[新线程3509]
[新线程3510]
[新线程3514]
[新线程3523]
[新线程3541]
[新线程3542]
[新线程3543]
[新线程4022]
[新线程4057]
[新线程4058]
[新线程4077]
[新线程4078]
[新线程4079]
[新线程4080]
[新线程6128]
[新线程6140]
[新线程6162]
[新线程6376]
[新线程6389]
[新线程6408]
[新线程6422]
[新线程6429]
[新线程6451]
[新线程6497]
[新线程6513]
[新线程6514]
[新线程6516]
[新线程6517]
[新线程6532]
[新线程6533]
[新线程6665]
[新线程6675]
[新线程6676]
[新线程6687]
[新线程6689]
[新线程6692]
[新线程6706]
[新线程6707]
[新线程6735]
[新线程6736]
[新线程7033]
[新线程7034]
[新线程7056]
[新线程7077]
[新线程7079]
【新线程7080】
[新线程7082]
[新线程7089]
[新线程7090]
[新线程7091]
[新线程7092]
[新线程7103]
[新线程7105]
[新线程7107]
[新线程7108]
[新线程7116]
[新线程7229]
[新线程7308]
[新线程 7493]
[新线程7505]
[新线程7510]
[新线程7511]
[新线程7517]
[新线程7523]
[新线程7604]
[新线程7617]
[新线程7618]
[新线程7619]
[新线程8676]
[新线程8693]
【新线程8700】
[新线程8851]
【新线程8860】
[新线程8887]
[新线程9007]
[新线程9118]
[新线程9119]
[新线程9120]
[新线程9413]
[新线程9427]
[新线程9495]
[新线程9508]
[新线程9519]
[新线程9535]
[新线程9536]
[新线程9537]
[新线程9554]
[新线程9556]
[新线程9659]
[新线程9660]
[新线程9663]
[新线程9664]
[新线程9665]
[新线程9666]
[新线程9667]
[新线程9668]
[新线程9669]
[新线程9670]
[新线程9671]
[新线程9678]
[新线程9870]
[新线程9953]
[新线程9998]
[新线程10002]
[新线程10118]
[新线程10119]
[新线程10122]
[新线程10149]
[新线程10152]
[新线程10155]
[新线程10176]
[新线程10178]
[新线程10179]
[新线程10180]
[新线程10182]
[新线程10194]
[新线程10195]
[新线程10196]
[新线程10198]
[新线程10199]
[新线程10200]
[新线程10201]
[新线程10202]
[新线程10203]
[新线程10205]
[新线程10206]
[新线程10244]
[新线程10246]
[新线程10247]
[新线程10248]
[新线程10249]
[新线程10251]
[新线程10252]
[新线程10254]
[新线程10255]
[新线程10256]
[新线程10257]
[新线程10258]
[新线程10259]
[新线程10260]
[新线程10261]
[新线程10262]
[新线程10263]
[新线程10264]
[新线程10265]
[新线程10267]
[新线程10268]
[新线程10269]
[新线程10271]
[新线程 10476]
[新线程 10477]
[新线程 10479]
[新线程10552]
[新线程10607]
[新线程10611]
[新线程10612]
[新线程10613]
[新线程10615]
[新线程10617]
[新线程10623]
[新线程10624]
[新线程10625]
[新线程10641]
[新线程10642]
[新线程10649]
[新线程10736]
[新线程 10742]
[新线程10756]
[新线程10758]
[新线程10760]
[新线程10761]
[新线程10762]
[新线程11278]
[新线程 11412]
[新线程11513]
[新线程11514]
[新线程2878]
(gdb) 退出

gbd那时我退出了,因为我对以及如何使用它来诊断这类问题一无所知。我什至不明白最后一个命令做了什么。值得注意的一点是,输出中正好有 134 行“新线程”行,如果每行都代表 JVM 中产生的一个新线程,那么这可能是 JVM 死亡的原因。

所以我的问题实际上是三折-

1)知道为什么该jmap命令可能会给出该错误消息吗?

2)任何想法gdb输出意味着什么?

3)任何想法如何使用gdb来进一步诊断这个问题?

4

3 回答 3

5

顺便说一句,jvisualvm 可以直接加载核心转储。但是您必须使用创建核心文件的同一 jvm。

于 2012-04-02T18:09:28.837 回答
5

核心文件是否大于 2GB?如果是这样,您可能会遇到与 JVM 附带的 libsaproc.so 的 Linux 版本有关的问题。

再次运行您的命令,但像这样:

strace -o out.txt -f $yourOriginalCommand

然后 'grep core.2878 out.txt' 并在 open() 系统调用上查找错误。它是否返回错误(E_XXXXX)或文件句柄号?

于 2012-04-03T19:05:13.257 回答
5

这让我很困扰,因为我有一个代表我需要分析的堆的核心文件,但我经常看到下面的异常消息:

sun.jvm.hotspot.debugger.NoSuchSymbolException:在任何已知库名称(libjvm.so、libjvm_g.so、gamma_g)中找不到符号“gHotSpotVMTypeEntryTypeNameOffset”

将 jre 从我的源机器(获取核心文件的机器)复制到目标机器中完全相同的文件夹,然后使用该 java 位置作为参数运行 jmap 对我有用。

因此,如果其他人遇到这种情况,请尝试以下步骤:
1. 通过 gdb 连接到核心文件并确认正在运行的进程正在使用的 java 二进制文件的位置:

    gdb --core=</path/to/core-file>

2.上面的输出将以类似的方式结束

[New Thread 22748]
**Core was generated by `/opt/blah/location/jre/bin/java -Xmx...'.**

3. 确保将匹配版本的 jre 复制到/opt/blah/location/目录中

  1. 然后启动 jmap 为:

    /opt/jdk1.8.0_09/bin/jmap -heap /opt/blah/location/jre/bin/java /path/to/core-file
    

    这应该成功连接到核心文件并打印出堆统计信息。如果是,那么你已经成功读取了核心文件

  2. 从那时起,您可以使用以下方法从核心文件成功生成 hprof:

    /opt/jdk1.8.0_09/bin/jmap -dump:format=b,file=my-file.hprof /opt/blah/location/jre/bin/java /path/to/core-file
    
于 2016-11-06T05:11:06.280 回答