編譯jdk和使用clion調試jdk


前言

我們都知道java程序是運行在jvm虛擬機上的,jdk里面很多native方法的實現都是在jvm源碼里面的。那么jvm是如何加載類,如何創建對象,線程同步的本質是什么?那些看不見的native方法到底干了什么?這些疑問使用baidu或許能了解個大概。但通過百度獲取的知識,如果自己沒有消化,只是臨時解決某個問題,或者面試的時候背誦一下。我想這是無意義的。因為過了一段時間后,你會忘了它。甚至一點印象都沒有了。那么怎么把這些知識深深的刻在腦海里呢。其實我覺得沒必要。為什么要記住這些死板的知識點呢。舉個例子,面試的時候面試官可能會問你java nio底層依賴的epoll機制一共有涉及幾個系統調用。答案是epoll_createepoll_ctlepoll_wait這三個。但真的有必要記住他們嗎。我想也就大概面試的時候會用到吧。而且還是面試一般開發崗位的時候會問到。其實找下jdk源碼不就知道了,沒必要刻意記住這些東西。接下來我會使用幾篇文章講解如何搭建本地jvm的調試環境,如何調試native方法。如何調試jvm啟動過程。當然這些只是打開jvm大門的鑰匙。要想深入理解還需要一點一滴的積累。

環境准備

我的操作系統:mac os Big Sur 版本11.4

  1. 下載clion,我的版本是2019.3.6
  2. git clone openjdk12
  3. 安裝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誕生了。它的目錄結構是這個樣子的

image-20210707074153901

使用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

image-20210707075906913

image-20210707092254331

image-20210707080037987

Run/Debug configurations

image-20210707080310143

設置斷點,進行debug

image-20210321183529036.png

此處只是簡單地演示了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。配置調試程序的參數。

image-20210706213127925

os_posix.cpp中設置斷點。

image-20210706213257341

可以看出最終調用pthread_cond_wait這個系統調用,線程等待在那里。

這只是一個簡單的例子演示了如何使用Clion調試java程序。按照這個方法就可以對任何native方法進行單步調試。

IDEA配合Clion遠程調試

上面我們實現了調試hotspot虛擬機。如果我想java程序和hotspot虛擬機一起調試,該如何實現呢?這就需要使用到jvm的遠程debug功能了。

比如新建一個簡單的spring boot項目,使用maven生成可執行的jar包。

clion配置如下:

image-20210707110734903

idea配置如下:

image-20210707110821812

這樣不論是在clion下設置斷點還是在idea下設置斷點,都可以進行單步調試啦。

總結

這篇文章簡單介紹了下調試openjdk的環境和工具的使用。后面會出幾期針對特點知識點的深入hotspot源碼的解析教程。敬請期待。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM