从核心转储中提取堆转储(hprof)

5

我现在有一个核心转储文件,我想提取堆转储。无论我尝试什么,我总是得到以下错误消息:

god@heaven:~$ sudo /opt/java-MyApp/bin/jmap -dump:format=b,file=my-file.hprof /opt/java-MyApp/bin/java /home/god/tmp/core
[sudo] password for god: 
Attaching to core /home/god/tmp/my-app-core-dump from executable /opt/java-MyApp/bin/java, please wait...
Error attaching to core file: Doesn't appear to be a HotSpot VM (could not find symbol "gHotSpotVMTypes" in remote process)
sun.jvm.hotspot.debugger.DebuggerException: Doesn't appear to be a HotSpot VM (could not find symbol "gHotSpotVMTypes" in remote process)
    at sun.jvm.hotspot.HotSpotAgent.setupVM(HotSpotAgent.java:411)
    at sun.jvm.hotspot.HotSpotAgent.go(HotSpotAgent.java:305)
    at sun.jvm.hotspot.HotSpotAgent.attach(HotSpotAgent.java:156)
    at sun.jvm.hotspot.tools.Tool.start(Tool.java:191)
    at sun.jvm.hotspot.tools.Tool.execute(Tool.java:118)
    at sun.jvm.hotspot.tools.HeapDumper.main(HeapDumper.java:83)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.tools.jmap.JMap.runTool(JMap.java:201)
    at sun.tools.jmap.JMap.main(JMap.java:130)

如果我尝试使用gdb打开核心文件,那么它会像魔法一样工作:

gdb --core core
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1
Copyright (C) 2016 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".
[New LWP 11241]
[New LWP 11242]
[New LWP 11243]
[New LWP 11244]
[New LWP 11245]
...
[New LWP 23423]
[New LWP 30560]
[New LWP 11240]
Core was generated by `/opt/java-MyApp/bin/java -Djava.util.logging.config.file=/opt/MyAp'.
#0  0x0000003c838cc0a6 in ?? ()
[Current thread is 1 (LWP 11241)]
(gdb) 

根据我阅读的所有资料,我应该确保在使用{{gcore}}生成core dump时,已经安装了与路径和版本相同的JVM。在完成这一步之后,我只需要使用确切的JVM调用jmpa:

sudo $JVM_USED_WHILE_GCORE_HOME/bin/jmap -dump:format=b,file=$OUTPUT_HPROF_FILE $JVM_USED_WHILE_GCORE_HOME/bin/java $CORE_FILE_PATH

我是否漏掉了什么?为什么我经常会收到“在远程进程中找不到符号'gHotSpotVMTypes'”的错误消息?


在gdb下,你能找到gHotSpotVMTypes符号吗? - apangin
所有的OpenJDK版本都不是吗?或者我应该检查什么? - Francisco Spaeth
我得到了:未加载符号表。请使用“file”命令。 - Francisco Spaeth
如果我执行 (gdb) file ~/Apps/jdk1.8.0_102/bin/java,我会得到 Reading symbols from ~/Apps/jdk1.8.0_102/bin/java...(no debugging symbols found)...done. 的输出。 - Francisco Spaeth
@apangin 谢谢,你引导我走向了正确的方向。问题基本上是Java被符号链接所引用,一旦我在本地创建了符号链接,我就可以提取堆转储文件了。 - Francisco Spaeth
显示剩余2条评论
1个回答

3
问题相当简单。/opt/java-MyApp/bin/java路径是一个符号链接。一旦我按照生成核心转储的机器上使用的结构重新创建了它,它就像魔法一样工作了。看来库是通过其规范路径使用的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接