mac下编译openjdk1.9及集成clion动态调试

晚上被小伙伴问道如何使用ide进行jvm源码的调试,刚好前段时间花了点时间折腾了一下,mac最新版本下jvm9顺利编译通过,并且可以完美集成clion进行调试(支持windows),下面记录一下全过程,如果想看效果的话,可以直接拉到集成到clion进行调试小节末尾

mac下openjdk源码编译过程

准备编译环境准备

我的mac的版本如下

image.png

由于openjdk1.9之前的版本对mac下编译支持得不是很流畅,所以这篇文章选择openjdk1.9

编译之前,首先你需要准备 homebrew,homwbrew是mac下的包管理器,如果你的mac上没有安装,可以按照下面的方式来安装

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

homwbrew下载完成之后,接下来准备编译环境

  • 首先安装openjdk的版本管理工具mercurial
  • 然后安装ccache和freetype,ccache用来加速编译,freetype在编译过程也会依赖到

上述准备编译环境的脚本为

brew install mercurial
brew install ccache
brew install freetype

请确保上述三个依赖安装成功再进行下面的步骤

源码获取

环境准备好之后,接下来获取源码,我这里工作目录是 ~/jvm,建议你也建一个此目录

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

这条命令运行之后,openjdk的源码并没有下载下来,我们随后进入到~/jvm/jdk9目录,会发现有一个 get_source.sh 的文件
调用这个脚本下载完整的源码之前,需要做一下简单的修改,不然可能你在下载源码的过程中会数次中断

get_source.sh文件最后几行的内容如下

# 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

然后,愉快地调用

bash ./get_source.sh

友情提醒:这个过程可能要持续1~2小时,请提前点好外卖

开始编译

源码下载完之后,我们开始编译,我们先进行编译前的配置

./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,需要替换成本机实际安装的版本

执行完之后,记下来会进行一系列的配置,这个过程时间要短很多,最后,如果出现如下的提示,那么恭喜你,接下来就可以执行编译了

image.png

接下来调用下面的脚本进行编译

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

编译完成之后,如果没有出现错误提示,那么再次恭喜你,你的第一个自行编译的openjdk版本已经顺利通过了,可以考虑打个赏来庆祝一下快乐的心情

最后,验证一下

image.png

编译过程中遇到的问题

我比较幸运,在编译过程中就只遇到过三个空指针转换的问题

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了一把,根据这篇文章,找到对应的源码文件的位置,把0强制转换成同一种类型
比如下面这个

image.png

好在一共只有三个地方,我都给你列出来了

#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进行调试

千呼万唤试出来,终于来到本小节的内容,相信很多小伙伴更想知道jvm源码编译完之后,如何在本机进行流畅地调试阅读源码,在这之前,我发现网上这方面的资料少得可怜,所以自己慢慢摸索出来,分享给大家

使用clion载入源码

首先,我们打开clion,选择 File->ImportProject,选择到 ~/jvm/jdk9/hotspot作为jvm源码的根目录,这里导入的过程无脑点击next即可

项目导入之后,clion会给你默认建立一个 CMakeLists.txt文件,这里可以不用管他,让他建,完成之后,clion会做大量的索引,索引建立完成之后,项目导入到此结束,界面如下

image.png

很多小伙伴遇到clion导入源码之后遇到头文件找不到的问题,而实际上这些头文件在源码里面是存在的,只不过在某些源文件里面是以相对路径的方式来搜索,可以在CMakeLists.txt里面添加一些根路径,我添加了如下根路经

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)

另外,如果某些头文件依然找不到,可以手工导入,然后把导入的头文件加到
hotspot/src/share/vm/precompiled/precompiled.hpp里,因为大多数源文件都会包含这个源文件,加到这个头文件,可以保证在能够引入缺失头文件的同时在debug的时候行数不会串掉,我在读源码的过程中添加了如下几个头文件

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>

构建调试环境

到了这里,源码的阅读环境才刚刚开始,没有debug,总觉得看起代码来不真实,于是,接下来我们继续构建自己的调试环境

image.png

右上角,我们点击Edit Configuration,进入到下面这个界面

image.png

我们创建一个调试环境


image.png

Executable选择编译好的二进制 java文件,然后在Before launch...选项中,干掉Build,就是说我们在debug的时候不需要再build,再说了,这里你也build不起来。
到了这里,一个可调试的jvm源码调试环境已经准备完毕了,下面我们来调试一把看看效果

我们来到 jni.cpp,在 JNI_CreateJavaVM_inner 这个方法上打个断点,点击右上角的debug,神奇的一幕出现了

image.png

方法调用栈,当前方法上下文环境,调试所需要的东西应有尽有,如果上面这个画面不够打动你的话,那么下面一张实际源码阅读过程中的动图呢?


3.gif

与java程序联合调试

我们想要修改jvm源码,修改完之后想要通过修改完的源码来运行我们的指定的java程序,由于clion默认的build工具无法build jvm,我们只能借助于make命令。
clion在debug的时候可以添加两个前置处理器,如下图

image.png

第一个前置处理器用于build jvm,第二个前置处理器用于compile java文件,这样,当你修改了点jvm源码,并且修改了java文件之后,在点击右上角的debug文件的时候,clion就会默认先执行jvm的编译,然后再进行java文件的编译,编译完之后就在 /Users/yuchao/IdeaProjects/jvm/src(我们在此目录下放置java源文件) 目录下生成 一个Main.class文件,然后就可以使用编译过后的jvm来运行,下面是构建jvm和编译java文件的两个external tool

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

最后,我们来看下,修改了jvm源码之后的效果


image.png

当然,你也可以在你的java ide中,把jdk选择自己编译的jdk,再执行,也是一样的效果


image.png

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342