从JVM崩溃日志中的堆栈跟踪获取行号

时间:2017-06-27 13:44:56

标签: java libgdx crash jvm stack-trace

我尝试使用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$1.run()V+27
v  ~StubRoutines::call_stub

一个特定的行涉及我自己的一些代码:

J 1422 C1 com.me.mygame.screens.IslandScreen.render(F)V (848 bytes) @ 0x0000000002e40624 [0x0000000002e3a4e0+0x6144]

有什么方法可以找到造成这种情况的特定行是什么?如果没有,可以做些什么来调试这次崩溃?

1 个答案:

答案 0 :(得分:1)

崩溃日志中的堆栈跟踪可能包含已解释和已编译的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

您需要最接近(但不超过)727的行号。在上例中,它是第67行。

或者,您可以请求JVM在崩溃之前执行命令。 jstack将有助于生成包含行号的完整线程转储。

java -XX:OnError="jstack -F %p" ...

此处-F表示“强制”模式,%p自动被JVM进程ID替换。

相关问题