环境
编译环境:Ubuntu 17.10 64位
openjdk版本:openjdk9
编译步骤
安装下载openjdk源码的工具
sudo apt install mercurial
下载源码
$ hg clone http://hg.openjdk.java.net/jdk9/dev 9dev
$ cd 9dev
$ sh ./get_source.sh
由于国内网络原因下载比较慢,下载失败的时候重复执行sh ./get_source.sh
直到全部下载完成为止。
安装jdk8
到oracle的官网上下载jdk8,我这里下载的版本是jdk-8u162-linux-x64.tar.gz
,解压下载的jdk文件到/opt/java
目录下,/opt
下没有java
目录则手动创建
tar -zxvf jdk-8u162-linux-x64.tar.gz -C /opt/java
设置java环境变量sudo vim /etc/profile
编辑profile
文件,在文件末尾添加以下内容
export JAVA_HOME=/opt/java/jdk1.8.0_162
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib/
export PATH=$PATH:$JAVA_HOME/bin
执行source /etc/profile
让我们新增的配置立即生效,执行java -version
判断jdk是否安装成功
note: 编译openjdk9需要使用jdk8作为
boot jdk
,因为我们编译的是openjdk9,最好安装oracle版本的jdk8作为boot jdk
,使用openjdk8有可能编译期间会出现各种问题
编译openjdk
执行如下命令来搜集系统配置信息
bash configure --disable-warnings-as-errors --with-debug-level=slowdebug --with-native-debug-symbols=internal
各参数表示的意义如下:
- –disable-warnings-as-errors 禁用编译器
warning
当做错误来处理 - –with-debug-level 设置编译级别,在这里我们要编译为能够debug的版本,因此设为slowdebug
- –with-native-debug-symbols 生成调试需要debug符号信息,并将这些信息写入到编译生成的二进制文件中,该参数一定要指定,否则用
gdb
调试的时候会提示找不到符号信息,无法设置断点
当看到如下信息时,说明configure
已经成功了
A new configuration has been successfully created in
/home/peter/Study/java/jdk/9dev/build/linux-x86_64-normal-server-slowdebug
using configure arguments '--disable-warnings-as-errors --with-debug-level=slowdebug --with-native-debug-symbols=internal'.
Configuration summary:
* Debug level: slowdebug
* HS debug level: debug
* JDK variant: normal
* JVM variants: server
* OpenJDK target: OS: linux, CPU architecture: x86, address length: 64
* Version string: 9-internal+0-adhoc.peter.9dev (9-internal)
Tools summary:
* Boot JDK: java version "1.8.0_162" Java(TM) SE Runtime Environment (build 1.8.0_162-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode) (at /opt/java/jdk1.8.0_162)
* Toolchain: gcc (GNU Compiler Collection)
* C Compiler: Version 7.2.0 (at /usr/bin/gcc)
* C++ Compiler: Version 7.2.0 (at /usr/bin/g++)
Build performance summary:
* Cores to use: 2
* Memory limit: 3922 MB
configure
期间可能会提示某些软件尚未安装,根据提示安装即可。configure
结束会在源码目录下生成build
目录,这里保存了各个编译版本的配置信息。
执行如下命令编译openjdk
make images
image
表示编译生成JRE
和JDK
镜像,具体更多的编译选项可参考源码目录下的文档common/doc/building.html
,当看到如下所示的信息时,表明openjdk已经编译成功了
Finished building target 'images' in configuration 'linux-x86_64-normal-server-slowdebug'
编译的结果在9dev/build/linux-x86_64-normal-server-slowdebug
目录下
调试openjdk
我这里是在虚拟机中编译的,配置比较差,因此我这里只用gdb
来进行调试,然后在宿主机上使用netbeans来阅读源代码。进入到9dev/build/linux-x86_64-normal-server-slowdebug/jdk/bin
,执行如下命令即可开始调试
gdb -tui java
如下图所示
在入main
函数处设置断点,然后使用gdb命令调试即可,需要注意调试过程可能会多次提示java
线程收到了SIGSEGV
信号二停止往下执行,这时只要在gdb中执行continue
命令即可
(gdb) r
Starting program: /home/peter/Study/java/jdk/9dev/build/linux-x86_64-normal-server-slowdebug/jdk/bin/java
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, main (argc=1, argv=0x7fffffffe088) at /home/peter/Study/java/jdk/9dev/jdk/src/java.base/share/native/launcher/main.c:95
(gdb) c
Continuing.
[New Thread 0x7ffff7fde700 (LWP 105558)]
Thread 2 "java" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff7fde700 (LWP 105558)]
0x00007fffe0dde513 in ?? ()
(gdb)
或者我们在run
之前执行如下命令忽略掉该信号,这样java
线程就不会block
住了,参考文档segmentation fault in the jvm
handle SIGSEGV noprint