2017-06-27 121 views
0

我试图修复在使用libGDX的某些代码中似乎是竞态条件的情况。发生这种特殊的竞争条件会导致JVM崩溃。从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] 

有什么办法,我可以找一下这是造成这个特定的线?如果没有,可以做些什么来调试这次崩溃?

+0

确保你没有实例化,清除或刷新渲染方法上的任何东西。 – Hllink

+0

由于该方法具有签名“void render(float)”,因此请在该类中查找该方法。然后,您可以查找“void end()”调用来查找正在进行调用的render方法中的特定行 –

+0

render()方法有多复杂?也许张贴可能会得到新鲜的眼睛,也许指出你做错了什么? –

回答

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 

您需要bci最接近(但不超过)727的行号。在ab例如它是第67行。


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

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

这里-F装置 '被迫' 模式和%p由JVM进程ID被自动替换。

+0

谢谢,我可以用jstack获得一行数字栈跟踪。 – fridgefish