當我們談Debug時,我們在談什麼(Debug實現原理)
本文將會講述JPDA的組成,Debugger的實現原理等。
程式異常了!
返回結果不對!
在我這兒正常啊。
每一次遇到這種異常的情況,要處理問題時,我們一定會想到
等我Debug一下,分分鐘解決。
而如果是線上的問題,我們一定會想
如果能debug一下該多好啊
我們在說起Debug的時候,一般是在IDE裡程式碼中加斷點,一步步跟蹤。然後觀察變數的值,觀察輸出等等。
這種在Debug工具,許多IDE中都有提供,像Eclipse, IDEA,NetBeans,甚至我們可以直接使用JDK自帶的jdb工具進行高度。這些工具都支援本地除錯和遠端除錯
那在我們加斷點,debug,單步除錯等一系列動作背後,是如何實現的呢?
說到這些,就不得不提JPDA(Java Platform Debugger Architecture)。我們每次使用的debug功能,都是靠JPDA的支撐實現的。
什麼是JPDA?
官方文件裡這樣介紹:
The Java Platform Debugger Architecture (JPDA) consists of three interfaces designed for use by debuggers in development environments for desktop systems.
我們看到,JPDA由三部分組成:
-
JVMTI(Java Virtual Machine Tool Interface)
-
JDWP(Java Debugger Wire Protocol)
-
JDI(Java Debug Interface)
熟悉JVM的朋友可能聽說過JVMPI和JVMDI,在JDK1.5他們統一被替換為JVMTI。
JVMTI
以前的文章裡我們提到過Class的hotSwap,就是通過Instrument實現class的redefine
和retransform
。
而本質上JVMTI是一個programming interface,主要用在開發和監控上。而且它提供了介面去觀察(inspect) 應用狀態和控制應用的執行。工具通過它提供的介面,可以進行如下功能的實現:
-
profiling
-
debuging
-
monitoring
-
thread analysis
-
coverage analysis
可以看到,我們使用到的debug,只是JVMTI提供的眾從能力中的一種。
JDWP
觀察過Java debug程序的同學也許有印象,以debug方式啟動的JVM程序,看起來是這樣的:
-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:63971,server=y,suspend=n
除了程序名之外,還在啟動引數裡包含agentlib:jdwp
這些。這個就是現在要介紹的JDWP。
什麼是JDWP?
Java Debug Wire Protocol,是debugger和它要debug的JVM之間進行通訊的協議。更多具體協議的細節這裡不介紹,感興趣的同學可以到這兒檢視:
http://docs.oracle.com/javase/6/docs/technotes/guides/jpda/jdwp-spec.html
注意,這僅僅是一個協議的格式,具體的傳輸實現不是由JDWP來實現的。我們的debugger執行的操作傳送到JDWP的實現上,然後再轉給JVMTI來具體控制。
JDI
JDI是三個模組中最高層的一個介面,通過JDI,debugger可以更方便的編寫符合JDWP格式的資料,用來進行除錯資料傳輸。JDI的引入,提高了開發debugger的效率。
所以,從整體上看,我們可以把JPDA看作一個兩個互相通訊的程式,所以我們可以在任意地點很方便的除錯另一個JVM上執行的程式。
我們每次在IDE裡進行程式碼除錯時,實質上是通過IDE裡的debugger這個介面執行GUI操作,然後通過JDI傳送資料到JDWP,再經過JVMTI最終實現程式的高度。
每次我們開啟IDE除錯一個Java應用的時候,或者遠端attach一個Java程序的時候,別忘了這個IDE背後的身影---JPDA。
PS:Tomcat啟動指令碼中也直接包含了debug方式啟動的功能,在命令列中輸入
catalina jpda start, Tomcat就以debug方式啟動了。
對於想了解原始碼但不想把原始碼以專案形式執行的同學,可以採用這種方式,然後使用遠端除錯的方式,把原始碼所在專案和這個attach起來就可以了。
也可以檢視這篇文章:怎樣除錯Tomcat原始碼