1. 概述
先聲明環境:
- Ubuntu18
- 安裝並配置好JDK11(openjdk version “11.0.1” 2018-10-16)
- 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+N
或Ctrl+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. 前期準備
- 編譯需要boot jdk(低版本貌似不行,建議11),所以必須配置好jdk相關環境變量。
- 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不會。
- 我們需要在項目根目錄下手動創建一個
CMakeLists.txt
,然後寫入如下內容:cmake_minimum_required(VERSION 3.14) # 這個設置不需要嚴格對應,自己建個測試項目複製過來這段即可 project(hotspot) file(GLOB_RECURSE SOURCE_FILES "*.cpp" "*.hpp" "*.c" "*.h") add_executable(hotspot ${SOURCE_FILES})
- reload changes重新加載
CMakeLists.txt
就會自動生成一個名稱爲hotspot的Run Configuration
,類型爲CMake Application。
5.2. 更改Run Configuration
但是這樣是不夠的,無法啓動,我們需要修改Run configuration
。
- 將Executable修改爲我們編譯生成的
build/linux-x86_64-normal-server-release/jdk/bin/java
程序 - 將下面的Before Launch下的build刪除掉
現在就可以利用這個配置進行調試了,可以利用Program arguments像平時一樣給java命令傳遞參數。
5.3. 打斷點
打開share/prims/jni.cpp
,給JNI_CreateJavaVM
函數打斷點。以調試模式運行:
我們可以像平時調試一樣單步進入、查看調用棧、查看運行線程、查看參數信息等
我們的調試之旅就到這裏了,有什麼問題歡迎留言