2011-03-14 89 views
5

我有一個Java應用程序,通過JNI調用遺留應用程序的大量不同的本地方法。但JVM在任何JNI調用之外的隨機位置隨堆棧轉儲崩潰。有時在GC期間崩潰,有時在課堂上課和其他地方。我懷疑一個或多個本地方法正在破壞JVM堆或其他數據結構。我需要知道這是哪個調用,所以我可以修復本地實現。如何調試JNI堆腐敗問題?

傳統應用程序是第三方DLL,我沒有源代碼和符號信息。爲了使它可以從Java調用,我構建了一個使用JNI調用約定的包裝器DLL。

完美的解決方案是一個擴展的JVM選項,強制JVM在每次JNI調用後自動檢查堆和其他數據結構的完整性。

你知道有什麼可以幫助嗎?

P.S.請不要告訴我在JVM和遺留應用程序之間建立套接字或管道層,因爲我們的要求不允許這樣做。這是關於錯誤檢測,而不是架構設計。

+0

我假設你知道'-Xcheck:jni'? – Erik 2011-03-14 22:00:54

+0

是的,但感謝提問。 – fernacolo 2011-04-20 21:22:13

+0

我有同樣的問題,如果這有幫助:/我有很多數據通過JNI旅行,偶爾我會得到一個損壞的地址和數據包數據。它把整個模擬過程搞砸了,這真的很煩人。 – 2011-05-12 19:21:47

回答

5

因爲我自己找不到解決方案,所以我最終在純C++中構建了一個沙盒進程,以確定問題。我的Java應用程序使用ProcessBuilder實例化沙箱進程,然後使用stdin和stdout與它進行通信。而不是JVM,它是實際加載並調用傳統DLL的沙箱。然後,我使用微軟的應用程序驗證程序監視沙箱進程,該應用程序驗證程序發現內存損壞問題 - 傳遞緩衝區的調用比預期的要小。在確定之後,我只是增加了Java應用程序中用作緩衝區的byte []的長度,現在JVM可以直接調用DLL而不使用沙箱。

總體而言,僅僅因爲JVM在每次JNI調用後沒有驗證堆的選項,我損失了將近10天。但至少現在如果有人發現崩潰,我們可以使用沙箱快速調試它。