2017-06-27 81 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