偶尔会看一点点JVM代码,所以尝试构建了一把最新的OpenJDK8
1.环境介绍
1)时间: 2015-05-13
2)系统: Linux haogrgr-vm 3.16.0-30-generic #40~14.04.1-Ubuntu SMP Thu Jan 15 17:43:14 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
3)Eclipse: Eclipse C/C++ 4.4
4)OpenJDK代码: http://hg.openjdk.java.net/jdk8u/jdk8u40
2.JDK安装
这里安装的是构建OpenJDK需要依赖的JDK, 一般是当前构建版本的上一个版本, 比如我们这里需要安装JDK7.
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java7-installer
sudo apt-get install oracle-java7-set-default
# 如果你要安装JDK8:
# sudo apt-get install oracle-java8-installer
# sudo apt-get install oracle-java8-set-default
# 可以JDK7和JDK8都安装, 然后使用oracle-java8-set-default来设置默认的JDK
安装完成后使用 java -version 验证一下是不是安装成功了.
3.安装hg(openjdk使用的版本控制工具(Mercurial))
下载源码需要使用到hg命令, 安装命令
sudo apt-get install mercurial
同样, 安装完后使用 hg --version 验证是否安装成功
4.安装构建依赖的软件包
根据下面的命令来安装
sudo apt-get build-dep openjdk-7
官方的构建文档里面使用的是sudo aptitude build-dep openjdk-7 由于ubuntu没有带aptitude,我就直接用apt-get了
5.下载源代码
这里下载OpenJDK8最新的版本, 我将源码放在 /home/haogrgr/opt/myopenjdk 中
cd /home/haogrgr/opt
hg clone http://hg.openjdk.java.net/jdk8u/jdk8u40 myopenjdk
cd myopenjdk
bash ./get_source.sh
下载完成后, 就可以开始准备构建了.
6.配置
1)根据官方构建文档, 先执行目录下的configure程序来配置. 配置生成后, 就可以开始构建了
bash ./configure --with-debug-level=slowdebug --enable-debug-symbols ZIP_DEBUGINFO_FILES=0
configure有不少的参数, 具体的参数可以通过 'bash ./configure --help' 查看
--with-debug-level=slowdebug 表示构建debug版本, openjdk8去掉了jvmg版本的构建
--enable-debug-symbols 和 ZIP_DEBUGINFO_FILES=0 主要是方便调试
2)根据官方文档, 将语言设置为 ASCII
export LANG=C
7.构建
准备都完成了, 可以开始构建了(linux-x86_64-normal-server-slowdebug在 myopenjdk/build 目录下面,上面configure生成的目录名)
make all CONF=linux-x86_64-normal-server-slowdebug ZIP_DEBUGINFO_FILES=0
等吧,这边i7大概用了7分钟
8.看看成果
cd /home/haogrgr/opt/myopenjdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin
./java -verion
openjdk version "1.8.0-internal-debug"
OpenJDK Runtime Environment (build 1.8.0-internal-debug-haogrgr_2015_05_13_09_49-b00)
OpenJDK 64-Bit Server VM (build 25.40-b25-debug, mixed mode)
结果感人~~~
再来试试编译运行个Java程序试试 在当前目录下新建一个Main.java文件, 内容如下
public class Main{
public static void main(String[] args){
System.out.println("hello world !");
}
}
编译,执行看看
./javac Main.java
./java Main
hello world !
结果再次感人~~~
9.使用gdb调试看看
在进行调试前, 我们需要设置一个环境变量, LD_LIBRARY_PATH, 该环境变量主要用于指定查找共享库(动态链接库)时除了默认路径之外的其他路径
#debug目录主要是一些jvm相关的so文件
exprot LD_LIBRARY_PATH=/home/haogrgr/opt/myopenjdk/build/linux-x86_64-normal-server-slowdebug/hotspot/linux_amd64_compiler2/debug
设置完后, 我们进入gdb, 在thread.cpp:219打个断点, thread.cpp:219对应的代码为:
// Base class for all threads: VMThread, WatcherThread, ConcurrentMarkSweepThread,
// JavaThread
Thread::Thread() {
// stack and get_thread
set_stack_base(NULL);
set_stack_size(0);
set_self_raw_id(0);
set_lgrp_id(-1);
开始gdb调试(执行我们上面写的Main程序)
gdb --args ./java Main
#进入gdb, 打断点, 然后运行
(gdb) break thread.cpp:219
(gdb) run
#可以看到下面的输出, 进入到了断点
Starting program: /home/haogrgr/opt/myopenjdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin/java Main
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff7fda700 (LWP 14194)]
[Switching to Thread 0x7ffff7fda700 (LWP 14194)]
Breakpoint 1, Thread::Thread (this=0x7ffff000c000)
at /home/haogrgr/opt/myopenjdk/hotspot/src/share/vm/runtime/thread.cpp:219
219 set_stack_base(NULL);
#看看当前的代码
(gdb) l
#输出
214 // JavaThread
215
216
217 Thread::Thread() {
218 // stack and get_thread
219 set_stack_base(NULL);
220 set_stack_size(0);
221 set_self_raw_id(0);
222 set_lgrp_id(-1);
223
现在已经可以用gdb调试了
10.在Eclipse中调试代码
使用gdb调试毕竟不方便, 所以我选择用熟悉的Eclipse来调试, 这里并不使用Eclipse构建, 只是调试代码, 所以不需要很复杂的配置
网上很多的资料都是过时的, 比如资料里面提到的一堆环境变量, 其实没必要, 再比如jvmg , 这个在openjdk8里面根本就没有了.
具体步骤如下
1)下载安装Eclipse C/C++ 版, 我下载的是最新的4.4
2)导入hotspot工程
~进入Eclipse, 选择导入import工程 -> C/C++ -> Existing Code as Makefile Project -> 单击 Next -> 进入工程配置界面
在界面中:
Project Name设为hotspot 这个可以自己选择
Existing Code Location是/home/haogrgr/opt/myopenjdk/hotspot
Toolchain那里选Linux GCC,然后按Finish.
~把/hotspot/src目录加入源码索引方便代码搜索, 右键hotspot工程 -> properties -> C/C++ General -> Paths and Symbols -> Source Location选项卡
-> 选择Add Folder 吧 hotspot/src目录加入
~设置启动类, 右键工程 -> Debug As -> Debug Configurations -> 右键左边的C/C++ Application -> New -> 进入Main选项卡
在选项卡中:
C/C++ Application 选择 /home/haogrgr/opt/myopenjdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin/java
因为我们这里不再eclipse里面编译,所以这里选上 Disable auto build
然后切换到Arguments选项卡, 输入Java的参数, 我们这里运行上面的Main类, 于是这里填上 Main 也就是我们要执行的Java程序
然后切换到Environment选项卡, 添加变量
LD_LIBRARY_PATH=/home/haogrgr/opt/myopenjdk/build/linux-x86_64-normal-server-slowdebug/hotspot/linux_amd64_compiler2/debug
JAVA_HOME=/home/haogrgr/opt/myopenjdk/build/linux-x86_64-normal-server-slowdebug/jdk/
CLASSPATH=.:/home/haogrgr/opt/myopenjdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin (因为我的Main类在/bin目录下)
3)点击下面的Apply保存
4)在eclipse中找到thread.cpp, 在219行打个断点
5)Debug运行上面配置的Debug, 可以看到顺利调到了断点
11.参考资料
http://hllvm.group.iteye.com/group/topic/39731
http://hg.openjdk.java.net/jdk8/jdk8/raw-file/tip/README-builds.html
http://javaagile.blogspot.com/2014/05/debugging-jvm.html
http://blog.csdn.net/hengyunabc/article/details/16912775
https://rkennke.wordpress.com/2012/07/27/hacking-hotspot-in-eclipse/
12.总结
我要是构建 openjdk7 那么网上的资料那么多, 应该碰到的问题会少点, 但是, 老用旧的,就一直是旧的,
总共弄了2天才成功, 主要是不会C++, 缺乏对C系工程结构的了解, 缺乏C系调试的知识(gdb)
了解了不少知识, 收获不少
写下过程, 方便大家, 少走点弯路