3.4. 在致命错误日志文件中配置调试符号

当 Java 应用因为 JVM 崩溃而停机时,会生成一个致命错误日志文件,例如: hs_error,java_error。这些错误日志文件在应用程序的当前工作目录中生成。crash 文件包含来自堆栈的信息。

流程

  1. 您可以使用 strip -g 命令删除所有调试符号。以下代码显示了一个未经过的 hs_error 文件示例:

    Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
    V  [libjvm.so+0xb83d2a]  Unsafe_SetLong+0xda
    j  sun.misc.Unsafe.putLong(Ljava/lang/Object;JJ)V+0
    j  Crash.main([Ljava/lang/String;)V+8
    v  ~StubRoutines::call_stub
    V  [libjvm.so+0x6c0e65]  JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+0xc85
    V  [libjvm.so+0x73cc0d]  jni_invoke_static(JNIEnv_*, JavaValue*, _jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, Thread*) [clone .constprop.1]+0x31d
    V  [libjvm.so+0x73fd16]  jni_CallStaticVoidMethod+0x186
    C  [libjli.so+0x48a2]  JavaMain+0x472
    C  [libpthread.so.0+0x9432]  start_thread+0xe2

    以下代码显示了剥离的 hs_error 文件示例:

    Stack: [0x00007ff7e1a44000,0x00007ff7e1b44000],  sp=0x00007ff7e1b42850,  free space=1018k
    Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
    V  [libjvm.so+0xa7ecab]
    j  sun.misc.Unsafe.putAddress(JJ)V+0
    j  Crash.crash()V+5
    j  Crash.main([Ljava/lang/String;)V+0
    v  ~StubRoutines::call_stub
    V  [libjvm.so+0x67133a]
    V  [libjvm.so+0x682bca]
    V  [libjvm.so+0x6968b6]
    C  [libjli.so+0x3989]
    C  [libpthread.so.0+0x7dd5]  start_thread+0xc5
  2. 输入以下命令检查您是否有相同的调试符号版本和严重错误日志文件:

    $ java -version
    注意

    您还可以使用 sudo update-alternatives --config 'java' 完成此检查。

  3. 使用 nm 命令确保 libjvm.so 具有 ELF 数据和文本符号:

    /usr/lib/debug/usr/lib/jvm/java-11-openjdk-11.0.14.0.9-2.el8_5/lib/server/libjvm.so-11.0.14.0.9-2.el8_5.x86_64.debug

其他资源