openjdk11源碼從編譯到clion調試

1. 概述

先聲明環境:

  1. Ubuntu18
  2. 安裝並配置好JDK11(openjdk version “11.0.1” 2018-10-16)
  3. Clion2019.2

可以在docker裏面編譯,利用ubuntu的鏡像,然後安裝相關依賴也不會影響到宿主機。

2. 下載OpenJDK11

其實我們搜索openjdk進入到jdk11特性列表頁面時,左邊有個Mercurial鏈接,從那就可以進入源碼列表了,在源碼列表選擇jdk->jdk11即進入了源碼頁面。

最終源碼鏈接在此 https://hg.openjdk.java.net/jdk/jdk11/

打開後選擇左邊的bz2或zip或gz格式的下載文件即可。

這裏我們選擇bz2(總共87MB)格式的文件,即最終下載鏈接在此 https://hg.openjdk.java.net/jdk/jdk11/archive/tip.tar.bz2
特意提供百度網盤鏈接 https://pan.baidu.com/s/1w91BX7-rF-6F1Dd_zly7dA 提取碼: 7a7k

之後就是解壓到特定無特殊字符名的文件夾了,就不再贅述了。

3. 目錄結構

解壓後目錄結構大致就是這樣

.
├── ADDITIONAL_LICENSE_INFO
├── ASSEMBLY_EXCEPTION
├── bin
├── build
├── configure //利用bash configure來做編譯前的準備工作
├── doc //裏面有各種幫助文件,可以教你怎麼編譯jdk
├── LICENSE
├── make
├── Makefile
├── README
├── src //主要源碼
└── test

3.1. src的目錄結構

我們用clion打開解壓後的目錄(src目錄的父目錄),等待掃描後,就可以利用Ctrl+Shift+NCtrl+Shift+F等快捷鍵快速搜索文件名或特定字符串。

.
├── bsd
├── demo
├── hotspot
├── java.base
├── java.compiler
├── java.datatransfer
├── java.desktop
├── java.instrument
├── java.logging
....同類省略
├── jdk.accessibility
├── jdk.aot
├── jdk.attach
├── jdk.charsets
...同類省略
├── linux
├── sample
├── solaris
└── utils

其中hotspot 就是Java虛擬機的Cpp源碼了,我們調試就只需要利用這個目錄下的文件即可。

如果想查看Java類中的本地方法是怎麼實現的,只需打開相應的文件夾找到相應的類名.c文件即可。

例如:查看String類的intern方法的實現。利用Ctrl+Shift+N打開文件名搜索string.c,即可看到src/java.base/share/native/libjava/String.c中的intern實現。

JNIEXPORT jobject JNICALL
Java_java_lang_String_intern(JNIEnv *env, jobject this)
{
    return JVM_InternString(env, this);
}

4. 編譯JDK

官方的編譯jdk的文檔在doc/building.md,通過這個可以瞭解很多信息。

4.1. 前期準備

  1. 編譯需要boot jdk(低版本貌似不行,建議11),所以必須配置好jdk相關環境變量。
  2. gcc/g++也是要的

實際上到這你就可以在解壓目錄下執行bash configure --disable-warnings-as-errors(後面的選項一定要加上,否則編譯不通過)。然後你會發現總是報錯不通過並提示未安裝相應文件,只需根據提示安裝即可。如:

configure: error: Could not find alsa! You might be able to fix this by running 'sudo apt-get install libasound2-dev'

重複步驟直到成功即可。

4.2. 正式編譯

實際上可以執行make help,會顯示編譯幫助

執行make

.....
Stopping sjavac server
Finished building target 'default (exploded-image)' in configuration 'linux-x86_64-normal-server-release'

編譯成功後的顯示如上。

編譯好的jdk文件會在build/linux-x86_64-normal-server-release/jdk目錄下,根我們平時下的jdk目錄結構是一樣的。

5. 調試JVM

之前我們已經利用clion在解壓目錄下(src目錄的父目錄)打開了項目。現在我們close project,然後再次file->open打開src/hotspot目錄。

5.1. 創建CMakeLists.txt

以前的Clion好像會自動生成CMakeLists.txt,我用的Clion2019.2不會。

  1. 我們需要在項目根目錄下手動創建一個CMakeLists.txt,然後寫入如下內容:
    cmake_minimum_required(VERSION 3.14) # 這個設置不需要嚴格對應,自己建個測試項目複製過來這段即可
    
    project(hotspot)
    
    file(GLOB_RECURSE SOURCE_FILES "*.cpp" "*.hpp" "*.c" "*.h")
    
    add_executable(hotspot ${SOURCE_FILES})
    
  2. reload changes重新加載CMakeLists.txt就會自動生成一個名稱爲hotspot的Run Configuration,類型爲CMake Application。

5.2. 更改Run Configuration

但是這樣是不夠的,無法啓動,我們需要修改Run configuration

  1. 將Executable修改爲我們編譯生成的build/linux-x86_64-normal-server-release/jdk/bin/java程序
  2. 將下面的Before Launch下的build刪除掉

Run Configuration
現在就可以利用這個配置進行調試了,可以利用Program arguments像平時一樣給java命令傳遞參數。

5.3. 打斷點

打開share/prims/jni.cpp,給JNI_CreateJavaVM函數打斷點。以調試模式運行:
調試模式
我們可以像平時調試一樣單步進入、查看調用棧、查看運行線程、查看參數信息等
調試截圖

我們的調試之旅就到這裏了,有什麼問題歡迎留言

6. 推薦資料

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章