mac下編譯openjdk1.9及集成clion動(dòng)態(tài)調(diào)試

晚上被小伙伴問(wèn)道如何使用ide進(jìn)行jvm源碼的調(diào)試,剛好前段時(shí)間花了點(diǎn)時(shí)間折騰了一下塘偎,mac最新版本下jvm9順利編譯通過(guò)疗涉,并且可以完美集成clion進(jìn)行調(diào)試(支持windows),下面記錄一下全過(guò)程吟秩,如果想看效果的話咱扣,可以直接拉到集成到clion進(jìn)行調(diào)試小節(jié)末尾

mac下openjdk源碼編譯過(guò)程

準(zhǔn)備編譯環(huán)境準(zhǔn)備

我的mac的版本如下

image.png

由于openjdk1.9之前的版本對(duì)mac下編譯支持得不是很流暢,所以這篇文章選擇openjdk1.9

編譯之前涵防,首先你需要準(zhǔn)備 homebrew闹伪,homwbrew是mac下的包管理器,如果你的mac上沒(méi)有安裝,可以按照下面的方式來(lái)安裝

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

homwbrew下載完成之后偏瓤,接下來(lái)準(zhǔn)備編譯環(huán)境

  • 首先安裝openjdk的版本管理工具mercurial
  • 然后安裝ccache和freetype杀怠,ccache用來(lái)加速編譯,freetype在編譯過(guò)程也會(huì)依賴到

上述準(zhǔn)備編譯環(huán)境的腳本為

brew install mercurial
brew install ccache
brew install freetype

請(qǐng)確保上述三個(gè)依賴安裝成功再進(jìn)行下面的步驟

源碼獲取

環(huán)境準(zhǔn)備好之后厅克,接下來(lái)獲取源碼赔退,我這里工作目錄是 ~/jvm,建議你也建一個(gè)此目錄

cd ~/jvm
hg clone http://hg.openjdk.java.net/jdk9/jdk9 jdk9

這條命令運(yùn)行之后证舟,openjdk的源碼并沒(méi)有下載下來(lái)硕旗,我們隨后進(jìn)入到~/jvm/jdk9目錄,會(huì)發(fā)現(xiàn)有一個(gè) get_source.sh 的文件
調(diào)用這個(gè)腳本下載完整的源碼之前女责,需要做一下簡(jiǎn)單的修改卵渴,不然可能你在下載源碼的過(guò)程中會(huì)數(shù)次中斷

get_source.sh文件最后幾行的內(nèi)容如下

# Get clones of all absent nested repositories (harmless if already exist)
sh ./common/bin/hgforest.sh clone "$@" || exit $?

# Update all existing repositories to the latest sources
sh ./common/bin/hgforest.sh pull -u

我們把上面幾行的腳本刪掉,替換成下面的腳本

# Get clones of all absent nested repositories (harmless if already exist)
sh ./common/bin/hgforest.sh clone "$@"

while [ $? -ne 0 ]
do
    sh ./common/bin/hgforest.sh clone "$@"
done

# Update all existing repositories to the latest sources
sh ./common/bin/hgforest.sh pull -u

while [ $? -ne 0 ]
do
    sh ./common/bin/hgforest.sh pull -u
done

然后鲤竹,愉快地調(diào)用

bash ./get_source.sh

友情提醒:這個(gè)過(guò)程可能要持續(xù)1~2小時(shí)浪读,請(qǐng)?zhí)崆包c(diǎn)好外賣

開(kāi)始編譯

源碼下載完之后,我們開(kāi)始編譯辛藻,我們先進(jìn)行編譯前的配置

./configure --with-target-bits=64 --with-freetype=/usr/local/Cellar/freetype/2.8.1 --enable-ccache --with-jvm-variants=server,client --with-boot-jdk-jvmargs="-Xlint:deprecation -Xlint:unchecked" --disable-zip-debug-info --disable-warnings-as-errors --with-debug-level=slowdebug 2>&1 | tee configure_mac_x64.log

注意碘橘,上面的freetype,需要替換成本機(jī)實(shí)際安裝的版本

執(zhí)行完之后吱肌,記下來(lái)會(huì)進(jìn)行一系列的配置痘拆,這個(gè)過(guò)程時(shí)間要短很多,最后氮墨,如果出現(xiàn)如下的提示纺蛆,那么恭喜你,接下來(lái)就可以執(zhí)行編譯了

image.png

接下來(lái)調(diào)用下面的腳本進(jìn)行編譯

export LANG=C
make all LOG=debug  2>&1 | tee make_mac_x64.log

編譯完成之后规揪,如果沒(méi)有出現(xiàn)錯(cuò)誤提示桥氏,那么再次恭喜你,你的第一個(gè)自行編譯的openjdk版本已經(jīng)順利通過(guò)了猛铅,可以考慮打個(gè)賞來(lái)慶祝一下快樂(lè)的心情

最后字支,驗(yàn)證一下

image.png

編譯過(guò)程中遇到的問(wèn)題

我比較幸運(yùn),在編譯過(guò)程中就只遇到過(guò)三個(gè)空指針轉(zhuǎn)換的問(wèn)題

vi src/share/vm/memory/virtualspace.cpp (char *)

image.png

vi src/share/vm/opto/lcm.cpp (unsigned char *)

image.png

vi src/share/vm/opto/loopPredicate.cpp (const TypeInt *)

image.png

然后奸忽,google了一把堕伪,根據(jù)這篇文章,找到對(duì)應(yīng)的源碼文件的位置栗菜,把0強(qiáng)制轉(zhuǎn)換成同一種類型
比如下面這個(gè)

image.png

好在一共只有三個(gè)地方欠雌,我都給你列出來(lái)了

#1\. src/hotspot/share/memory/virtualspace.cpp # l585

if (base() != NULL) {

#2\. src/hotspot/share/opto/lcm.cpp # l42

if (Universe::narrow_oop_base() != NULL) { // Implies UseCompressedOops.

#3\. src/hotspot/share/opto/loopPredicate.cpp # l915

assert(rng->Opcode() == Op_LoadRange || iff->is_RangeCheck() || _igvn.type(rng)->is_int()->_lo >= 0, "must be");

集成到clion進(jìn)行調(diào)試

千呼萬(wàn)喚試出來(lái),終于來(lái)到本小節(jié)的內(nèi)容疙筹,相信很多小伙伴更想知道jvm源碼編譯完之后富俄,如何在本機(jī)進(jìn)行流暢地調(diào)試閱讀源碼检号,在這之前,我發(fā)現(xiàn)網(wǎng)上這方面的資料少得可憐蛙酪,所以自己慢慢摸索出來(lái),分享給大家

使用clion載入源碼

首先翘盖,我們打開(kāi)clion桂塞,選擇 File->ImportProject,選擇到 ~/jvm/jdk9/hotspot作為jvm源碼的根目錄馍驯,這里導(dǎo)入的過(guò)程無(wú)腦點(diǎn)擊next即可

項(xiàng)目導(dǎo)入之后阁危,clion會(huì)給你默認(rèn)建立一個(gè) CMakeLists.txt文件,這里可以不用管他汰瘫,讓他建狂打,完成之后,clion會(huì)做大量的索引混弥,索引建立完成之后趴乡,項(xiàng)目導(dǎo)入到此結(jié)束,界面如下

image.png

很多小伙伴遇到clion導(dǎo)入源碼之后遇到頭文件找不到的問(wèn)題蝗拿,而實(shí)際上這些頭文件在源碼里面是存在的晾捏,只不過(guò)在某些源文件里面是以相對(duì)路徑的方式來(lái)搜索,可以在CMakeLists.txt里面添加一些根路徑哀托,我添加了如下根路經(jīng)

image.png
include_directories(./src/share/vm)
include_directories(./src/cpu/x86/vm)
include_directories(./src/share/vm/precompiled)
include_directories(./src/share/vm/utilities)

另外惦辛,如果某些頭文件依然找不到,可以手工導(dǎo)入仓手,然后把導(dǎo)入的頭文件加到
hotspot/src/share/vm/precompiled/precompiled.hpp里胖齐,因?yàn)榇蠖鄶?shù)源文件都會(huì)包含這個(gè)源文件,加到這個(gè)頭文件嗽冒,可以保證在能夠引入缺失頭文件的同時(shí)在debug的時(shí)候行數(shù)不會(huì)串掉呀伙,我在讀源碼的過(guò)程中添加了如下幾個(gè)頭文件

image.png

# include <cstdlib>
# include <cstdint>
# include "register_x86.hpp"
# include "assembler_x86.hpp"
# include "globalDefinitions.hpp"
# include "globalDefinitions_x86.hpp"
# include "assembler_x86.hpp"
#include <stubRoutines_x86.hpp>

構(gòu)建調(diào)試環(huán)境

到了這里,源碼的閱讀環(huán)境才剛剛開(kāi)始添坊,沒(méi)有debug区匠,總覺(jué)得看起代碼來(lái)不真實(shí),于是帅腌,接下來(lái)我們繼續(xù)構(gòu)建自己的調(diào)試環(huán)境

image.png

右上角驰弄,我們點(diǎn)擊Edit Configuration,進(jìn)入到下面這個(gè)界面

image.png

我們創(chuàng)建一個(gè)調(diào)試環(huán)境


image.png

Executable選擇編譯好的二進(jìn)制 java文件速客,然后在Before launch...選項(xiàng)中戚篙,干掉Build,就是說(shuō)我們?cè)赿ebug的時(shí)候不需要再build溺职,再說(shuō)了岔擂,這里你也build不起來(lái)位喂。
到了這里,一個(gè)可調(diào)試的jvm源碼調(diào)試環(huán)境已經(jīng)準(zhǔn)備完畢了乱灵,下面我們來(lái)調(diào)試一把看看效果

我們來(lái)到 jni.cpp塑崖,在 JNI_CreateJavaVM_inner 這個(gè)方法上打個(gè)斷點(diǎn),點(diǎn)擊右上角的debug痛倚,神奇的一幕出現(xiàn)了

image.png

方法調(diào)用棧规婆,當(dāng)前方法上下文環(huán)境,調(diào)試所需要的東西應(yīng)有盡有蝉稳,如果上面這個(gè)畫面不夠打動(dòng)你的話抒蚜,那么下面一張實(shí)際源碼閱讀過(guò)程中的動(dòng)圖呢?


3.gif

與java程序聯(lián)合調(diào)試

我們想要修改jvm源碼耘戚,修改完之后想要通過(guò)修改完的源碼來(lái)運(yùn)行我們的指定的java程序嗡髓,由于clion默認(rèn)的build工具無(wú)法build jvm,我們只能借助于make命令收津。
clion在debug的時(shí)候可以添加兩個(gè)前置處理器饿这,如下圖

image.png

第一個(gè)前置處理器用于build jvm,第二個(gè)前置處理器用于compile java文件撞秋,這樣蛹稍,當(dāng)你修改了點(diǎn)jvm源碼,并且修改了java文件之后部服,在點(diǎn)擊右上角的debug文件的時(shí)候唆姐,clion就會(huì)默認(rèn)先執(zhí)行jvm的編譯,然后再進(jìn)行java文件的編譯廓八,編譯完之后就在 /Users/yuchao/IdeaProjects/jvm/src(我們?cè)诖四夸浵路胖胘ava源文件) 目錄下生成 一個(gè)Main.class文件奉芦,然后就可以使用編譯過(guò)后的jvm來(lái)運(yùn)行,下面是構(gòu)建jvm和編譯java文件的兩個(gè)external tool

image.png
image.png
image.png
image.png

最后剧蹂,我們來(lái)看下声功,修改了jvm源碼之后的效果


image.png

當(dāng)然,你也可以在你的java ide中宠叼,把jdk選擇自己編譯的jdk先巴,再執(zhí)行,也是一樣的效果


image.png

[參考資料]
https://segmentfault.com/a/1190000008346240
https://liuzhengyang.github.io/2017/04/28/buildopenjdk/
http://www.reibang.com/p/746963f28245
https://bugs.openjdk.java.net/browse/JDK-8187787

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末冒冬,一起剝皮案震驚了整個(gè)濱河市伸蚯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌简烤,老刑警劉巖剂邮,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異横侦,居然都是意外死亡挥萌,警方通過(guò)查閱死者的電腦和手機(jī)绰姻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)引瀑,“玉大人狂芋,你說(shuō)我怎么就攤上這事『┰裕” “怎么了帜矾?”我有些...
    開(kāi)封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)徒像。 經(jīng)常有香客問(wèn)我,道長(zhǎng)蛙讥,這世上最難降的妖魔是什么锯蛀? 我笑而不...
    開(kāi)封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮次慢,結(jié)果婚禮上旁涤,老公的妹妹穿的比我還像新娘。我一直安慰自己迫像,他們只是感情好劈愚,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著闻妓,像睡著了一般菌羽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上由缆,一...
    開(kāi)封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天注祖,我揣著相機(jī)與錄音,去河邊找鬼均唉。 笑死是晨,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的舔箭。 我是一名探鬼主播罩缴,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼层扶!你這毒婦竟也來(lái)了箫章?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤镜会,失蹤者是張志新(化名)和其女友劉穎炉抒,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體稚叹,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡焰薄,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年拿诸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片塞茅。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡亩码,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出野瘦,到底是詐尸還是另有隱情描沟,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布鞭光,位于F島的核電站吏廉,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏惰许。R本人自食惡果不足惜席覆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望汹买。 院中可真熱鬧佩伤,春花似錦、人聲如沸晦毙。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)见妒。三九已至孤荣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間须揣,已是汗流浹背垃环。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留返敬,地道東北人遂庄。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像劲赠,于是被迫代替她去往敵國(guó)和親涛目。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355