从 JVM 崩溃日志中的堆栈跟踪获取行号
Getting line numbers from a stack trace in a JVM crash log
我正在尝试使用 libGDX 修复某些代码中出现的竞争条件。这种特殊的竞争条件在发生时会导致 JVM 崩溃。
通过 JVM 崩溃日志搜索,我发现了以下几行:
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
J 1128 com.badlogic.gdx.utils.BufferUtils.copyJni([FLjava/nio/Buffer;II)V (0 bytes) @ 0x0000000002d477b0 [0x0000000002d47740+0x70]
J 1365 C2 com.badlogic.gdx.graphics.g2d.SpriteBatch.flush()V (185 bytes) @ 0x0000000002e16ad4 [0x0000000002e16940+0x194]
J 1201 C1 com.badlogic.gdx.graphics.g2d.SpriteBatch.end()V (90 bytes) @ 0x0000000002d8f2d4 [0x0000000002d8f1c0+0x114]
J 1422 C1 com.me.mygame.screens.IslandScreen.render(F)V (848 bytes) @ 0x0000000002e40624 [0x0000000002e3a4e0+0x6144]
J 1539 C1 com.badlogic.gdx.Game.render()V (25 bytes) @ 0x0000000002e6c1dc [0x0000000002e6c000+0x1dc]
j com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop()V+698
j com.badlogic.gdx.backends.lwjgl.LwjglApplication.run()V+27
v ~StubRoutines::call_stub
有一行涉及我自己的一些代码:
J 1422 C1 com.me.mygame.screens.IslandScreen.render(F)V (848 bytes) @ 0x0000000002e40624 [0x0000000002e3a4e0+0x6144]
有什么方法可以找到导致此问题的特定行吗?如果没有,可以做些什么来调试这个崩溃?
崩溃日志中的堆栈跟踪可能包含解释和编译的 Java 方法。
解释方法(用小 j
表示)也将包括字节码索引 (bci),例如
j com.me.mygame.screens.IslandScreen.render(F)V+727
^^^
此处方法 render
正在执行位置 727 处的字节码。要将其与行号匹配,请使用 Java 反编译器,例如 javap
:
javap -c -verbose -cp CLASSPATH com.me.mygame.screens.IslandScreen
寻找 LineNumberTable
将源代码中的行映射到字节码索引:
LineNumberTable:
line 7: 0
line 8: 11
...
line 66: 707
line 67: 719 <-- find the nearest bci
line 68: 731
您需要 bci 最接近(但不超过)727 的行号。在上面的示例中是第 67 行。
或者,您可以请求 JVM 在崩溃前立即执行命令。 jstack
将有助于生成包括行号的完整线程转储。
java -XX:OnError="jstack -F %p" ...
这里的-F
表示'forced'模式,%p
自动替换为JVM进程ID。
我正在尝试使用 libGDX 修复某些代码中出现的竞争条件。这种特殊的竞争条件在发生时会导致 JVM 崩溃。
通过 JVM 崩溃日志搜索,我发现了以下几行:
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
J 1128 com.badlogic.gdx.utils.BufferUtils.copyJni([FLjava/nio/Buffer;II)V (0 bytes) @ 0x0000000002d477b0 [0x0000000002d47740+0x70]
J 1365 C2 com.badlogic.gdx.graphics.g2d.SpriteBatch.flush()V (185 bytes) @ 0x0000000002e16ad4 [0x0000000002e16940+0x194]
J 1201 C1 com.badlogic.gdx.graphics.g2d.SpriteBatch.end()V (90 bytes) @ 0x0000000002d8f2d4 [0x0000000002d8f1c0+0x114]
J 1422 C1 com.me.mygame.screens.IslandScreen.render(F)V (848 bytes) @ 0x0000000002e40624 [0x0000000002e3a4e0+0x6144]
J 1539 C1 com.badlogic.gdx.Game.render()V (25 bytes) @ 0x0000000002e6c1dc [0x0000000002e6c000+0x1dc]
j com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop()V+698
j com.badlogic.gdx.backends.lwjgl.LwjglApplication.run()V+27
v ~StubRoutines::call_stub
有一行涉及我自己的一些代码:
J 1422 C1 com.me.mygame.screens.IslandScreen.render(F)V (848 bytes) @ 0x0000000002e40624 [0x0000000002e3a4e0+0x6144]
有什么方法可以找到导致此问题的特定行吗?如果没有,可以做些什么来调试这个崩溃?
崩溃日志中的堆栈跟踪可能包含解释和编译的 Java 方法。
解释方法(用小 j
表示)也将包括字节码索引 (bci),例如
j com.me.mygame.screens.IslandScreen.render(F)V+727
^^^
此处方法 render
正在执行位置 727 处的字节码。要将其与行号匹配,请使用 Java 反编译器,例如 javap
:
javap -c -verbose -cp CLASSPATH com.me.mygame.screens.IslandScreen
寻找 LineNumberTable
将源代码中的行映射到字节码索引:
LineNumberTable:
line 7: 0
line 8: 11
...
line 66: 707
line 67: 719 <-- find the nearest bci
line 68: 731
您需要 bci 最接近(但不超过)727 的行号。在上面的示例中是第 67 行。
或者,您可以请求 JVM 在崩溃前立即执行命令。 jstack
将有助于生成包括行号的完整线程转储。
java -XX:OnError="jstack -F %p" ...
这里的-F
表示'forced'模式,%p
自动替换为JVM进程ID。