編譯jdk和使用clion除錯jdk
前言
我們都知道java程式是執行在jvm虛擬機器上的,jdk裡面很多native方法的實現都是在jvm原始碼裡面的。那麼jvm是如何載入類,如何建立物件,執行緒同步的本質是什麼?那些看不見的native方法到底幹了什麼?這些疑問使用baidu
或許能瞭解個大概。但通過百度獲取的知識,如果自己沒有消化,只是臨時解決某個問題,或者面試的時候背誦一下。我想這是無意義的。因為過了一段時間後,你會忘了它。甚至一點印象都沒有了。那麼怎麼把這些知識深深的刻在腦海裡呢。其實我覺得沒必要。為什麼要記住這些死板的知識點呢。舉個例子,面試的時候面試官可能會問你java nio底層依賴的epoll機制一共有涉及幾個系統呼叫。答案是epoll_create
epoll_ctl
,epoll_wait
這三個。但真的有必要記住他們嗎。我想也就大概面試的時候會用到吧。而且還是面試一般開發崗位的時候會問到。其實找下jdk原始碼不就知道了,沒必要刻意記住這些東西。接下來我會使用幾篇文章講解如何搭建本地jvm的除錯環境,如何除錯native
方法。如何除錯jvm啟動過程。當然這些只是開啟jvm大門的鑰匙。要想深入理解還需要一點一滴的積累。
環境準備
我的作業系統:mac os Big Sur 版本11.4
- 下載
clion
,我的版本是2019.3.6
git clone openjdk12
- 安裝jdk11,編譯jdk12需要使用引導的jdk,否則會提示
Your Boot JDK version must be one of 11,12
編譯jdk
進入openjdk的根目錄執行
bash configure --disable-warnings-as-errors --with-debug-level=slowdebug --with-jvm-variants=server make images # disable-warnings-as-errors選項是禁止把warning 當成error # --with-debug-level=slowdebug。用來設定編譯的級別,可選值為release、fastdebug、slowde-bug,越往後進行的優化措施就越少,帶的除錯資訊就越多。預設值為release。slowdebug 含有最豐富的除錯資訊,沒有這些資訊,很多執行可能被優化掉,我們單步執行時,可能看不到一些變數的值。所以最好指定slowdebug 為編譯級別。 # with-jvm-variants 編譯特定模式的HotSpot虛擬機器,可選值:server、client、minimal、core、zero、custom
configure 命令承擔了依賴項檢查
、引數配置
和構建輸出目錄結構
等多項職責,如果編譯過程中需要的工具鏈或者依賴項有缺失,命令執行後會得到明確的提示,並給出該依賴的安裝命令。
漫長的等待之後,一個自己的jdk誕生了。它的目錄結構是這個樣子的
使用clion除錯hotspot虛擬機器
下面的操作主要參考這篇部落格https://blog.jetbrains.com/clion/2020/03/openjdk-with-clion/
compilation database 這個功能大概的意思就是clion
預設是用cmake
,但是編譯openjdk
是用make
,可以通過下面這個辦法解決
If you are working with a project which is not based on CMake, Gradle, or Makefiles, you can still benefit from the advanced IDE features that CLion provides. One way is to import a non-CMake project and let CLion convert it into a simple CMake structure. Another option is to open a project by loading its compilation database
生成compile_commands.json
檔案
make compile-commands
使用CLion File=> Open => 選擇檔案
/jdk12/build/macosx-x86_64-server-slowdebug/compile_commands.json
選擇open as Project
這時候,你會發現你是看不到原始碼的,所以下面需要修改專案的根目錄,通過Tools -> Compilation Database -> Change Project Root
功能,選中你的原始碼目錄,也就是jdk12
Custom Build Targets
Run/Debug configurations
設定斷點,進行debug
此處只是簡單地演示了java -version
如何debug。那如果是一個普通的java程式如何debug呢。
寫一個測試程式如下:
public class Demo {
public static void main(String[] args) throws Exception {
LockSupport.park();
}
}
檢視原始碼發現park方法實際呼叫的是Unsafe
類的park方法。而這個native
方法的原始碼位於/jdk12/src/hotspot/share/runtime/park.hpp
下,它的實現類是/jdk12/src/hotspot/os/posix/os_posix.cpp
。配置除錯程式的引數。
在os_posix.cpp
中設定斷點。
可以看出最終呼叫pthread_cond_wait
這個系統呼叫,執行緒等待在那裡。
這只是一個簡單的例子演示瞭如何使用Clion
除錯java程式。按照這個方法就可以對任何native
方法進行單步除錯。
IDEA配合Clion遠端除錯
上面我們實現了除錯hotspot虛擬機器。如果我想java程式和hotspot虛擬機器一起除錯,該如何實現呢?這就需要使用到jvm的遠端debug功能了。
比如新建一個簡單的spring boot專案,使用maven生成可執行的jar包。
clion配置如下:
idea配置如下:
這樣不論是在clion下設定斷點還是在idea下設定斷點,都可以進行單步除錯啦。
總結
這篇文章簡單介紹了下除錯openjdk的環境和工具的使用。後面會出幾期針對特點知識點的深入hotspot原始碼的解析教程。敬請期待。