在Ubuntu14下构建Hotspot并使用Eclipse调试

坚强是说给别人听的谎言 提交于 2019-12-01 02:17:58

偶尔会看一点点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://github.com/codefollower/Open-Source-Research/blob/master/HotSpot1.7-JVM-Linux-x86/my-docs/%E6%9E%84%E5%BB%BA%E4%B8%8E%E8%B0%83%E8%AF%95.md  

   https://rkennke.wordpress.com/2012/07/27/hacking-hotspot-in-eclipse/  

   https://neomatrix369.wordpress.com/2013/03/12/hotspot-is-in-focus-again-aka-hacking-hotspot-in-eclipse-juno-under-ubuntu-12-04/


12.总结

   我要是构建 openjdk7 那么网上的资料那么多, 应该碰到的问题会少点, 但是, 老用旧的,就一直是旧的, 

   总共弄了2天才成功, 主要是不会C++, 缺乏对C系工程结构的了解, 缺乏C系调试的知识(gdb)

   了解了不少知识, 收获不少

   写下过程, 方便大家, 少走点弯路



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!