
??????作為一個程序員,每天都會遇到問題、調(diào)試代碼。常見的調(diào)試一般是加日志、打斷點。在java中添加日志,每次都要編譯,極其不便。java作為一門成熟的語言,怎么能沒有成熟的機制?我們平時一般會用IDE自帶的調(diào)試工具,eclipse、Intellij 等。本文將講解一下java debug 體系的基礎(chǔ)知識。

1 JPDA (Java platform debug Architecture)體系介紹
??????我們在調(diào)試的過程中,一般需要一些方法來觀察和測試運行態(tài)中的環(huán)境信息,比如變量、狀態(tài)、jvm 狀態(tài)、堆棧信息等。這些通過JPDA都可以搞到。
2 JPDA結(jié)構(gòu)

??????JPDA定義了一個完整獨立的體系,它由三個相對獨立的層次共同組成,而且規(guī)定了三者之間的交互方式。這三個層次由低到高依次是Java 虛擬機工具接口(JVMTI),Java 調(diào)試線協(xié)議(JDWP)以及 Java 調(diào)試接口(JDI)。這三個模塊把調(diào)試過程分解成幾個很自然的概念:調(diào)試者(debugger)和被調(diào)試者(debuggee),以及他們中間的通信器。
3 JPDA三層結(jié)構(gòu)的交互

基本交互可以分為如下步驟:
3.1、jvmti 相關(guān)的步驟
- jvm啟動,注冊JVMTI:jvm啟動時,會檢查對應(yīng)的jvm參數(shù),加載jvmti。
- jvm啟動, jdwp以agent的方式加載,并且設(shè)置對應(yīng)的callback函數(shù)。啟動jdwp的監(jiān)聽socket ;并且會初始化一個eventQueue實例,用戶后續(xù)跟jdi 進行event交互。event 共有18種。(這個過程可以在啟動時加載,也可以jvm其中之后以attach的方式加載 你假笨的jvm attach機制實現(xiàn))。具體的jvm啟動過程可以看一些我的這篇文章:jvm啟動 ;
3.2、JDI相關(guān)的步驟
上述步驟主要描述了一下jvmti 相關(guān)的啟動,下面講一下JDI相關(guān)的步驟(以斷點調(diào)試為例):
- 從Intellij建立Remote debug, 此時就是建立了一個socket連接(上面步驟中jdwp agent 已經(jīng)建立了socket ,等待客戶端的連接)
- 建立完連接,第一件事情就是雙方進行handshake 交互,彼此之間確認對方使用的都是jdwp協(xié)議。
- Intellij 設(shè)置斷點,就是通過jdi 的eventRequestManage 生成一個類型為breakpoint event 并且?guī)в衒ilter(保證只在特定地方生效)的eventRequest, 然后按照jdwp協(xié)議組裝成command ,發(fā)送給目標jvm.
3.3、目標jvm的處理
- 目標jvm接收到來自調(diào)試端的command 指令,會解析指令
- 目標jvm 運行,當觸發(fā)breakpoint event 且滿足調(diào)試端的filter 規(guī)則時 ,將這個breakpoint event加入到breakpoint eventSet 中
- 然后 eventQueue 實例會將eventSet 按照FIFO的順序返回給調(diào)試端。當然返回之前會將結(jié)果按照jdwp協(xié)議組裝成reply 命令返回。
4 總結(jié)
本文講述了JPDA的概述,組成部分,重點講述了組成部分之間的交互流程。后面的文章將展開講述這幾個組成部分。
本系列其他文章鏈接:
jvm啟動流程圖
jvmti agent的加載與回調(diào)函數(shù)的執(zhí)行分析
java debug 體系-jdi
java debug 體系-jdwp
java debug 體系-JVMTI