Java 从JVM致命错误日志猜测方法行号
我有一个没有核心转储的致命错误日志,需要确定原因。 这是在.log文件中找到的堆栈:Java 从JVM致命错误日志猜测方法行号,java,jvm,jvm-crash,Java,Jvm,Jvm Crash,我有一个没有核心转储的致命错误日志,需要确定原因。 这是在.log文件中找到的堆栈: # Problematic frame: # C [libc.so.6+0x7b4bb] memcpy+0x15b {…} 正如我在另一个StackOverflow答案中所读到的,在替换jvm需要加载的任何.jar时,这可能是一个常见错误(或硬件内存错误) 我想猜测的是导致这个致命错误的.jar文件。有没有办法用致命错误日志中的信息来识别源代码中的行号 我本来希望这行末尾的“V+72”有什么关系,但我想不
# Problematic frame:
# C [libc.so.6+0x7b4bb] memcpy+0x15b
{…}
正如我在另一个StackOverflow答案中所读到的,在替换jvm需要加载的任何.jar时,这可能是一个常见错误(或硬件内存错误)
我想猜测的是导致这个致命错误的.jar文件。有没有办法用致命错误日志中的信息来识别源代码中的行号
我本来希望这行末尾的“V+72”有什么关系,但我想不出来。这可能最终无助于解决问题,但它回答了部分问题: 正如他在评论中已经猜到的,
+72
只是字节码偏移量。我用一个小程序对此进行了测试:
(其他方面无关,只是从另一个问题中快速获得)
本机genTerrain
函数通过调用
jclass errorClass = env->FindClass("XXX");
env->NewObjectArray(10, errorClass, NULL);
导致核心转储
堆栈如下所示:
Stack: [0x0000000002500000,0x0000000002600000], sp=0x00000000025ff4e0, free space=1021k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [jvm.dll+0x14ebb6]
C [TestNativeArray3D.dll+0x397d] JNIEnv_::NewObjectArray+0x4d
C [TestNativeArray3D.dll+0x3ae8] Java_TestNativeArray3D_genTerrain+0x98
C 0x0000000002715534
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j TestNativeArray3D.genTerrain(III)[[[I+0
j TestNativeArray3D.main([Ljava/lang/String;)V+11
v ~StubRoutines::call_stub
这里,类似地包含(可能)偏移的线是
jtestnativeArray3D.main([Ljava/lang/String;)V
+11
使用反编译类
文件时
javap -c -l TestNativeArray3D
(注意-l
(小“l”)以获得行号!)输出为
class TestNativeArray3D {
TestNativeArray3D();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 3: 0
public static void main(java.lang.String[]);
Code:
0: ldc #2 // String TestNativeArray3D
2: invokestatic #3 // Method java/lang/System.loadLibrary:(Ljava/lang/String;)V
5: bipush 123
7: bipush 8
9: bipush 6
11: invokestatic #4 // Method genTerrain:(III)[[[I
14: astore_1
15: return
LineNumberTable:
line 7: 0
line 8: 5
line 9: 15
}
类TestNativeArray3D{
TestNativeArray3D();
代码:
0:aload_0
1:invokespecial#1//方法java/lang/Object。“:()V
4:返回
LineNumberTable:
第3行:0
公共静态void main(java.lang.String[]);
代码:
0:ldc#2//String TestNativeArray3D
2:invokestatic#3//方法java/lang/System.loadLibrary:(Ljava/lang/String;)V
5:bipush 123
7:bipush 8
9:bipush 6
11:invokestatic#4//方法genTerrain:(III)[[I]
14:astore_1
15:返回
LineNumberTable:
第7行:0
第8行:5
第9行:15
}
实际上,本机调用发生在offset11
(是的,我通过在调用之前添加一些进一步的代码进行了反检查:核心转储中的偏移量会相应地改变)
“LineNumberTable”允许您在字节码偏移量和行之间进行映射
- 源代码第7行对应字节码偏移量0
- 源代码第8行对应字节码偏移量5
- 源代码行9对应字节码偏移量15
invokestatic
调用。我只想指出,您可以查找LineNumberTable,以查找字节码偏移量到源代码中实际行number的映射)
不幸的是,这很难帮助您真正解决错误,因为这一错误显然是在
libc.so
的本机代码中更深层次造成的,在一些memcpy
期间,显然从libzip.so
收到了无效的指针。因此,…我还阅读了oracle关于致命错误日志文件的文档,但是idn没有帮助。“V”只是表示它是一个无效的方法。我怀疑+72是方法中的字节码偏移量,但我不会发誓。有人对此投了反对票——可能是因为他认为这可能被视为“与请求调试帮助无关”或者是这样。但事实上,这对许多开发人员来说是一个有趣且相关的问题,所以我向上提了一个问题。用-Xint再次运行您的程序,看看它是否仍然失败。java-Xint-myProgram.Report backThank you@HotLicks。我正试图匹配IntelliJ报告的字节码,但有很多评论。这似乎不准确。谢谢Marco,和@HotLicks是关于使用javap的初始提示。正如您所指出的,这并不能解决错误,但至少可以给我一个关于jvm加载jar试图实现什么的线索。
javap -c -l TestNativeArray3D
class TestNativeArray3D {
TestNativeArray3D();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 3: 0
public static void main(java.lang.String[]);
Code:
0: ldc #2 // String TestNativeArray3D
2: invokestatic #3 // Method java/lang/System.loadLibrary:(Ljava/lang/String;)V
5: bipush 123
7: bipush 8
9: bipush 6
11: invokestatic #4 // Method genTerrain:(III)[[[I
14: astore_1
15: return
LineNumberTable:
line 7: 0
line 8: 5
line 9: 15
}