2012-07-21 49 views
1

當本地方法調用(直接或間接)某個Linux系統調用時,如何在Java中產生斷點?Linux系統調用的Java斷點

+0

一個非常奇怪的要求。你能解釋一下背景嗎?或許可以找到解決問題的其他方法? – 2012-07-21 08:20:07

+0

我想看看我沒有編寫的任意應用程序,並且方便地確定他們爲什麼告訴操作系統執行某些操作。我不滿意於在Java API調用中放置一個斷點,因爲可能有多種方法來執行某些操作,而且對於來自定製JNI代碼的操作系統調用而言,這些方法根本不起作用。 – 2012-07-21 09:01:26

回答

0

理論上,可以使用Java的提前(AOT)編譯器本地編譯應用程序,然後使用本地調試器在系統調用上設置斷點或catchpoint。 (獎勵:然後您將得到一個完整的堆棧跟蹤,包括本地方法調用的所有C函數,以及無縫調試這些C函數的能力。)

您可能想要使用調試器,該調試器知道如何取名由AOT編譯器生成。例如,gdb知道如何去掉gcj產生的名字,所以gdb的gcj組合應該可以工作。

與之相結合的問題在於,GCJ仍然停留在部分 JDK 1.5的兼容性,並沒有被人不屑於做的OpenJDK的類庫合併的工作(有人建議在GCJ郵件列表2009)。因此,gcj從未成爲流行的選擇 - 人們通常會無意中使用它(特別是在Debian和Ubuntu上),但是當它們遇到問題時,他們傾向於轉向更標準的JDK,而不是報告錯誤。

使用AOT編譯器進行本地編譯也比僅在它認爲有必要時讓JRE JIT編譯代碼慢得多。

1

這不是一個斷點,但至少它會給你一個堆棧跟蹤,這可能是你所需要的。此外,如果需要,Systemtap語言允許您執行更多操作,而不僅僅是打印堆棧跟蹤。

在IcedTea JVM源代碼中,您會發現一個SystemTap file函數,該函數可用於從正在運行的IcedTea(使用Hotspot)JVM獲取堆棧跟蹤。據我瞭解,使用這些函數,您可以從SystemTap支持的任何事件(甚至是來自內核事件)獲取Java堆棧跟蹤。

請注意,儘管具有相同的名稱,但這些jstack函數與JDK提供的jstack(1)命令行實用程序無關。它們通過內存檢查工作,而不是通過回調到JVM,因此它們是quite specific to Hotspot internals,因此可能不適用於基於非熱點的JVM。

注意:Systemtap does not fully work on default Debian kernels,因此您可能需要在基於Debian的系統上編譯自己的內核。這個問題不會影響Fedora或Red Hat。