0%

MacOS 10.14.5 + Xcode 10编译调试OpenJDK10

概述

标题说是OpenJDK10,实际上把OpenJDK8、9、10、12都试了一个遍。环境如下,注意需要一个安装好的JDK作为"Boot JDK"。

  • MacOS 10.14.5
  • Xcode 10.3(10G8),Apple LLVM version 10.0.1 (clang-1001.0.46.4)
  • Oracle JDK8(build 1.8.0_192-b12) 这个环境下编译OpenJDK8就不用试了毕竟太老了。编译OpenJDK9、OpenJDK10需要把libstdc++放到Xcode里面,但编译OpenJDK9时到最后的编译阶段JVM启动时Crash了,但编译OpenJDK10是成功的,因此本人目前在这个环境下编译成功的OpenJDK最低版本是OpenJDK10。

至于OpenJDK12,什么都不用做直接编译基本就OK了。

编译OpenJDK10

还原libstdc++

因为Xcode10里面把libstdc++干掉了,所以编译OpenJDK10之前先要把libstdc++弄回来。 这也是我写这篇文章的主要目的,因为网上虽然有些朋友指出了这个方法,也提供了lib库下载,但要么只提供了iOS相关的文件,要么只提供了MacOS下的lib文件没有提供头文件...

最后我去苹果官网下载了Xcode9的安装包,解压提取了MacOS下libstdc++的lib文件和头文件,这里给需要的朋友提供下载地址:https://cdn.spirithy.com/code/xcode/XCode9 Dump.zip

下载解压后,把"MacOSX"下对应的文件复制到/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++和/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib/ 目录下即可。

下载源码

安装Mercurial后,直接hg下载源码。可能比较慢,也可以到官网手动下载源码压缩包。

1
hg clone http://hg.openjdk.java.net/jdk10/jdk10/ jdk10

安装依赖和编译

依赖主要是openssl、freetype之类的,用brew安装即可,ccache可有可无。源码下载好后,先执行configure,注意下freetype路径:

1
./configure --with-debug-level=slowdebug --disable-warnings-as-errors --with-freetype-include=/usr/local/Cellar/freetype/2.10.1/include/freetype2 --with-freetype=/usr/local/Cellar/freetype/2.10.1
然后执行"make all"基本就可以了,编译好后的文件在build目录下。
1
make all

Docker下编译OpenJDK8

如果还不死心,想编译一把OpenJDK8,基本上比较靠谱的方法就是用Docker了。

Docker容器准备

Docker镜像最好是用CentOS,因为里面的各种工具链都比较老... 注意Docker run时加了"--cap-add=SYS_PTRACE --security-opt"这些安全相关的参数,这样后面才能在Docker容器中愉快地debug。

这里用的CentOS 7,除了安装基本的依赖外,还安装了一个OpenJDK 7作为Boot JDK。

1
2
3
4
5
6
docker run --cap-add=SYS_PTRACE --security-opt --name builder -v /Users/spirit/Projects/openjdk/:/var/spirit/openjdk -i -t centos:centos7 /bin/bash

yum -y update
yum -y groupinstall "Development Tools"
yum -y install unzip libXtst-devel libXt-devel libXrender-devel cups-devel freetype-devel alsa-lib-devel which wget vim
yum -y install java-1.7.0-openjdk-devel

下载源码

下载源码跟前面下载OpenJDK10一样。这里提一下,因为OpenJDK源码是分模块的,需要想切换到某个tag,除了根目录要用"hg up"切之外,几个子目录也不要忘记了。

1
hg clone http://hg.openjdk.java.net/jdk8/jdk8 jdk8

编译前的准备

如果直接编译是会报错的,因为Makefile里面支持的linux内核只写到了3.X,估计当时4.X内核还没出。去把 /hotspot/make/linux/Makefile文件中声明的SUPPORTED_OS_VERSION,在最后加上"4%" 即可。

编译

configure阶段比较简单:

1
./configure --with-debug-level=slowdebug
编译阶段直接"make all"可能会遇到报错"cc1: all warnings being treated as errors",网上的其它方法都不管用,其实用make SCTP_WERROR="" all就行了,详见:http://openjdk.5641.n7.nabble.com/Re-Build-error-with-GCC4-8-on-Fedora19-td143112i20.html
1
make SCTP_WERROR="" all

关于调试

调试暂时没有结合CLion、VS Code之类的IDE来做,而是直接直接用的lldb、gdb(cgdb)来调试的。 稍微记录下注意事项和常用命令。

lldb(MacOS下OpenJDK10)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 带参数启动
lldb -- /Users/spirit/Projects/openjdk/jdk10/build/macosx-x86_64-server-slowdebug/jdk/bin/java -version

# attach到指定进程
pro att -p 9939

# 下条件断点
br set --file verifier.cpp --line 171 -c '(int)strcmp("Serializer_1", klassName)==0'

# 禁用断点
br disable 1

# 启动断点
br enable 1

gdb(CentOS7下OpenJDK8)

首先,调试的时候如果报找不到调试信息"Missing separate debuginfo for/var/spirit/openjdk/jdk8/build/linux-x86_64-normal-server-slowdebug/jdk/lib/amd64/server/libjvm.so",是因为在编译时因为编译配置项不正确而没有生成调试的符号信息,或生成后被压缩为”libjvm.diz”了,所以无法找到。如果是因为没有编译时没有生成调试信息,需要修改编译配置并重新编译。对于被压缩的情况,可以去到"libjvm.so"所在目录解压:unzip libjvm.diz。

1
2
3
4
5
6
7
8
9
10
11
# 带参数启动
cgdb --args /var/spirit/openjdk/jdk8/build/linux-x86_64-normal-server-slowdebug/jdk/bin/java "-cp" "/root/fastjson-test-1.0.0-SNAPSHOT-jar-with-dependencies.jar" "com.spirit.vdefineb.DefineTest"

# 下条件断点
b verifier.cpp:121 if (int)strcmp("Serializer_1", klassName)==0

# 禁用断点
disable 1

# 启动断点
enable 1