openjdk9u源码分析一:搭建环境(原创)

openjdk9u源码分析一:搭建环境

搭建环境可分两步,
  1. 搭建jdk9u编译环境
  2. 搭建jdk9u调试环境
实验环境
   1. Mac OS X: 10.13.3.
   2. Xcode: 9.2.
   3. boot jdk: 1.8.0_162.
   4. freetype: 2.9.
   5. XQuartz-2.7.11.
   6. GDB-8.0.1.

1.搭建jdk9u编译环境

  • 目标:从官网下载openjdk9u源码,正确编译打包出jdk9u可执行文件,能够编译、运行helloworld程序。
  • 搭建过程:参考https://www.yanshuo.me/p/156958,按照这篇文章能够正确编译出可运行的jdk9u。我的环境和参考链接中的基本上一致,除了使用的boot jdk,我使用的1.8.0_162,而参考文章使用的1.8.0_161。
  • 结果验证:
  • 编译后的结果位于源码根目录/build下:


    build-result-tree.jpg

目前阶段只关注hotspot、images和jdk子目录,其中hotspot存放jvm的编译结果,images存放jdk、jrem,doc等产品文件,jdk存放jdk编译结果。

  • 验证build出来的jdk版本:


    build-version.jpg
  • Run一个helloworld类:


    helloworld-verify.jpg
  • 问题总结:

    1. 网上资料以编译jdk7、8为主,总结比较全面的文章请参考https://github.com/ydcun/Java/blob/master/java/src/main/java/com/ydcun/openjdk/jdk8/MAC%E7%BC%96%E8%AF%91OpenJDK8.md,折腾了半天jdk8的编译,把hotspot8u40给捣腾出来了,但在运行hotspot时提示找不到libjvm.dylib:

    unable to load native library:dlopen(/Library/Java/JavaVirtualMachines jdk1.7.0_10.jdk/Contents/Home/jre/lib/libjava.dylib, 1):Symbol not found: \_JVM\_SetProtectionDomain Referenced from: /Library/Java/JavaVirtualMachines/jdk1.7.0\_10.jdk/Contents/Home/jre/lib/libjava.dylib Expected in: /Users/Desktop/hotspot-68577993c7db/build/bsd/ bsd\_amd64\_compiler2/fastdebug/libjvm.dylib

    这个错误应该是没有编译jdk8u40的源码,只编译了hotspot的源码,我用boot jdk7代替了jdk8造成的,但并没有实际去验证。看了jdk9u的文章后,里面提到“因为编译8需要Xcode 4现在Xcode版本已远高于4了”,就放弃了jdk8的编译,但现在看,未必是Xcode的版本影响了8的编译。

    1. 在编译jdk8时,要求安装XQuartz,我安装了XQuartz-2.7.11,但并未能创建这两个链接:
      sudo ln -s /usr/X11/include/X11 /usr/include/X11
      or
      sudo ln -s /usr/local/X11/include/X11 /usr/include/X11
      后面编译成功说明这个问题可以忽略。
    2. 源码推荐从http://hg.openjdk.java.net/jdk-updates下载。首先下载根目录,然后再分别下载各个子目录,下载完后解压到根目录下,如下图所示:
      folder-tree.jpg
src-download.jpg

其中,hotspot是JVM的源码目录,jdk存放jdk源码,强烈建议在编译之前先读common/doc/下的build文件。其他目录的功能说明大家可网上了解即可,对于编译过程,基本没影响,如果要运行jdk自带的测试代码,需要关注test目录。 其他两种下载源码的方式:使用Mercurial的hg,openjdk的源码通过mercurial进行管理。但正如网友@since1986在博文中所述,每次都是下载到一定大小的内容后,程序自动退出;还有网友修改了get_source.sh脚步,使之自动重连下载,修改的脚步比较多,而且不保证能成功,放弃。另外,git上有上传的代码,参见https://github.com/luodaxu/blog-1/blob/master/Java/hotspot-debug-under-osx.md,但并未验证。

  1. 设置环境变量。
  • 设置boot jdk path。方便起见,下载了jdk7,jdk8两个版本,jdk7用于实验,8用于工作,如果想直接编译jdk9,jdk7也不需要额外安装。
        export JAVA\_8\_HOME=$(/usr/libexec/java\_home \-v1.8)  
        export JAVA\_7\_HOME=$(/usr/libexec/java\_home \-v1.7)  
        alias java7='export JAVA\_HOME=$JAVA\_7\_HOME' 
        alias java8='export JAVA\_HOME=$JAVA\_8\_HOME'  
        \# default java8  
        export JAVA_HOME=$JAVA\_8\_HOME
  • 设置编译参数。每个参数上都有说明,大家自行查阅,并可以根据实验机器的配置进行调整。本文仅对build和compile的job数进行了修改,编译一遍通过。
        \# 设定语言选项,必须设置  
        export LANG=C  
        \# Mac平台,C编译器不再是GCC,是clang  
        export CC=clang  
        \# 跳过clang的一些严格的语法检查,不然会将N多的警告作为Error  
        export COMPILER\_WARNINGS\_FATAL=false
        \# 链接时使用的参数  
        export LFLAGS='\-Xlinker \-lstdc++'  
        \# 是否使用clang  
        export USE\_CLANG=true  
        \# 使用64位数据模型  
        export LP64=1
        \# 告诉编译平台是64位,不然会按32位来编译  
        export ARCH\_DATA\_MODEL=64  
        \# 允许自动下载依赖  
        export ALLOW\_DOWNLOADS=true  
        \# 并行编译的线程数,编译时间长  
        export HOTSPOT\_BUILD\_JOBS=8  
        ALT\_BOOTDIR=$JAVA\_HOME  
        export ALT\_PARALLEL\_COMPILE\_JOBS=2  
        \# 是否跳过与先前版本的比较  
        export SKIP\_COMPARE\_IMAGES=true  
        \# 是否使用预编译头文件,加快编译速度  
        export USE\_PRECOMPILED\_HEADER=true  
        \# 是否使用增量编译  
        export INCREMENTAL\_BUILD=true  
        \# 编译内容  
        export BUILD\_LANGTOOLS=true  
        export BUILD\_JAXP=true  
        export BUILD\_JAXWS=true  
        export BUILD\_CORBA=true  
        export BUILD\_HOTSPOT=true  
        export BUILD\_JDK=true  
        \# 编译版本  
        export SKIP\_DEBUG\_BUILD=true  
        export SKIP\_FASTDEBUG\_BUILD=false  
        export DEBUG\_NAME=debug  
        \# 避开javaws和浏览器Java插件之类的部分的build  
        export BUILD\_DEPLOY=false  
        export BUILD\_INSTALL=false  
  • configure时添加--disable-warnings-as-errors。因为在build hotspot时,如果出现warnings,编译过程会认为失败,实际这些warnings不影响编译的正确性;也可以在环境变量中配置:export COMPILER_WARNINGS_FATAL=false,上述配置已包括。
  1. 有些jvm源码需要修改,详情参见上述参考的链接。

  2. jdk9的模块化等一些新特性不会影响编译过程,正如jdk的一位负责人所说,从老版本迁移到jdk9要比之前的升级过程还简单,至少从编译jdk源码的过程来讲,jdk9u并未增加额外的工作量。

  3. mac下软件安装时,可能会遇到verify stuck的情况,参考http://osxdaily.com/2016/07/26/fix-stuck-pkg-verifying-installer-mac-os-x/解决。

    至此,openjdk9u已经编译成功,并得到一个可用于调试的jvm和jdk。接下来,使用已构建的程序包,调试一个helloworld的程序。该过程网上信息比较少,已有的资料要么jdk版本不一致,要么依赖的软件包版本不同,要么操作系统不同,对于之前未debug jvm的dev,可能是个痛苦的过程,但参考下面的内容后,将会使大家的调试过程变得轻松许多。

搭建jdk9u调试环境

  • 目标:利用已生成的jvm,debug一个java helloworld程序,且能够debug到jvm的源码。
  • 搭建过程:针对jdk8的调试环境搭建,请参考http://blog.csdn.net/tjiyu/article/details/53725247。整个过程可概况为使用GDB(全平台通用)或LLDB(windows版本正在开发,其他平台都支持)debug java这个可执行文件(GDB、LLDB是两种C、C++程序调试工具,由于hotspot主要采用C++和C实现,因此要调试hotspot必须要使用C、C++的调试工具,这些工具可以通过命令行单条执行命令,也可以通过脚步批量执行),入参为待执行的java class文件名,本文中为Test。java可执行文件启动一个hotspot实例来执行Test class。下面分步骤说明环境搭建过程。
  1. 安装GDB。 macOsX high sierra下,Xcode9.2默认使用LLDB,因此需要安装GDB。从GDB官网下载了最新的8.1版本,并安装网上的说明进行sign,否则debug时,eclipse的进度条会一直卡在99%不动。参考https://stackoverflow.com/questions/18423124/please-check-gdb-is-codesigned-see-taskgated8-how-to-get-gdb-installed-w对GDB进行签名,需要注意:证书类型需要先选择login方式,然后再拖拽到system类型下,否则创建证书会报错。如下图所示:
    gdb-cert-kind.jpg

后来验证的过程说明,GDB相关的问题是调试环境安装过程中最大的一个坑。
* 添加"set startup-with-shell off" >> ~/.gdbinit,.gdbinit是gdb的初始化文件,也可以在执行gdb之前执行set startup-with-shell off。
* 执行csrutil status,查看Debugging Restrictions配置项的值,如果是enabled,需要更改为disabled。参考https://stackoverflow.com/questions/39702871/gdb-kind-of-doesnt-work-on-macos-sierra/40437725#40437725,需要reboot,并在安全模式下执行。
* 回退到8.0.1版本,事实证明8.1.0与OS X 10.13.3兼容性不好。参见https://gist.github.com/gravitylow/fb595186ce6068537a6e9da6d8b5b96d。在因为GDB抛出"During startup program terminated with signal SIGTRAP, Trace/breakpoint trap."问题时,曾尝试使用LLDB进行debug,但LLDB虽然能跑完测试程序,但看不到java程序的输出,最终还是使用GDB进行调试时看到了java的输出。LLDB调试参见https://github.com/luodaxu/blog-1/blob/master/Java/hotspot-debug-under-osx.md,但通过LLDB与GDB的对比,也找到了GDB不能输出的原因,即在gdb捕获segment invalid异常时,继续执行,在hotspot脚步中添加handle SIGSEGV nostop这一行指令。后面在介绍hotspot脚步时还会详细介绍。通过一个C程序验证GDB已成功安装。

  1. 修改Hotspot文件。该脚步位于./jdk9u-1b1226687b89/build/macosx-x86_64-normal-server-slowdebug/hotspot/variant-server/libjvm/下,它是一个可执行的脚步文件,该文件配置了JDK路径、GDB调试器默认的一些参数,关于该文件的内容可参考《HotSpot实战》这本书第一章的内容或https://yq.aliyun.com/articles/93753?spm=a2c4e.11153940.blogcont93737.16.6da64d09stvTm2。需要说明的有三点:
    * build源码后,该脚步中已经添加了已build的jdk路径,大家可查看hotspot文件中的这一行: JDK=/Users/Desktop/jdk9u-1b1226687b89/build/macosx-x86_64-normal-server-slowdebug/jdk
    * 脚步中init_gdb()函数用于配置gdb参数,默认生成的内容中有handle SIGUSR1 nostop noprinthandle SIGUSR2 nostop noprint这两行,handle命令的意思是debug过程中,gdb如何处理系统信号,在后面添加handle SIGSEGV nostop这一行。
  2. 复制libjvm.dylib文件到hotspot脚步相同目录下。最初通过“./jdk9u-1b1226687b89/build/macosx-x86_64-normal-server-slowdebug/hotspot/variant-server/libjvm/hotspot -gdb Test”测试时,总是得到一个ERROR“Error: missing /Users/.../Desktop/jdk9u-1b1226687b89/build/macosx-x86_64-normal-server-slowdebug/hotspot/variant-server/libjvm' JVM at/Users/Desktop/jdk9u-1b1226687b89/build/macosx-x86_64-normal-server-slowdebug/hotspot/variant-server/libjvm/libjvm.dylib'.
    Please install or use the JRE or JDK that contains these missing components.”
    ,该错误耽误了有半天的时间,最初依赖搜索引擎,但网上在mac high sierra下调试hotspot9的资料基本上没有,只是了解到libjvm就是hotspot的动态库,当时真有些山穷水尽的感觉,于是只能中断一些时间,休息时,libjvm.dylib missing的错误一直在头脑中浮现,某个时刻突然想到libjvm.dylib文件是不是不在hotspot相同目录下,于是查找hotspot/variant-server/libjvm/目录,发现该文件在./libjvm/gtest下,copy一份到hotspot/variant-server/libjvm,即与hotspot文件同目录下,测试Test,得到了期待的结果:
    final-verify.png

图中,绿色方框中的为java程序的输出,红色框中即为GDB收到的segment fault的信号,如果不修改hotspot脚步,GDB会执行不下去。

  • 问题总结:
  • 使用当前比较新的软件版本做一些实验时,网上可参考资料很少,如果对一些问题领域不太熟悉,可能会花费较多的时间和精力;
  • 实验遇到瓶颈时,抓住错误日志不放,休息后换个思路再试;
  • 多尝试不同的思路才可能解决问题;
  • 遇到问题请教网上的专家得到响应的情况几乎为零:(。
    本文知识产权归创造者所有,复制转发发行需经作者同意。

加入公众号获取我的更多原创文章:

公众号二维码1.jpg

加入“Java编程思想读书会”微信群,和大量技术专家们讨论技术:

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

推荐阅读更多精彩内容

  • 最近准备阅读JVM源码,打算在本机编译一个Debug版本的JDK,鉴于工作中主要使用JDK7,因此选择OpenJd...
    allanYan阅读 1,419评论 3 0
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,049评论 25 707
  • 什么是微习惯 微习惯:就是把一个习惯大幅缩减成小到不可思议的步骤。微习惯是一种非常微小的积极行为,目标太小,小到不...
    颖公子6阅读 209评论 0 0
  • Firefly是Amazon在2014年推出手机Fire时的核心功能,主要是识别,包括图形、语音、文字、音频bla...
    妖精王国的猫小姐阅读 356评论 1 2
  • 早上的时间,看了成长的好好学习的序言,关键词,模型框架,临界知识,底层规律,,书上,讲到人学习的目标有三个方面,无...
    灵动心光阅读 217评论 0 0