你們也能夠看個人博客: openjdk7之編譯和debug,這裏格式更好。php
爲了更好的學習JDK、HotSpot等源碼,須要能debug JDK、HotSpot等源碼。本文主要講述,怎麼編譯openjdk並debug相關源碼。
在本文中,要編譯的openjdk:openjdk-7u40-fcs-src-b43-26_aug_2013.zip
系統環境爲ubuntu 16.04,uname -a:java
Linux ddy-Aspire-V5-573G 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
bash java version "1.6.0_45" Java(TM) SE Runtime Environment (build 1.6.0_45-b06) Java HotSpot(TM) Server VM (build 20.45-b01, mixed mode)
sudo apt-get install build-essential
sudo apt-get install ant
sudo apt-get install libxrender-dev
sudo apt-get install xorg-dev
sudo apt-get install libasound2-dev
sudo apt-get install libcups2-dev
sudo apt-get install gawk zip libxtst-dev libxi-dev libxt-dev
配置編譯腳本
將你的openjdk解壓後,並進入該文件夾。好比個人是在/home/ddy/openjdk-compile/openjdk-7u40-fcs-b43-26/openjdk
下。新建一個build.sh,並添加以下內容:
```bash
export LANG=C
#將一下兩項設置爲你的BootstrapJDK安裝目錄
export ALT_BOOTDIR=/home/ddy/jdk1.6.0_45
export ALT_JDK_IMPORT_PATH=/home/ddy/jdk1.6.0_45
#容許自動下載依賴包
export ALLOW_DOWNLOADS=truelinux
#使用預編譯頭文件,以提高便以速度
export USE_PRECOMPILED_HEADER=truec++
#要編譯的內容,我只選擇了LANGTOOLS、HOTSPOT以及JDK
export BUILD_LANGTOOLS=true
export BUILD_JAXP=false
export BUILD_JAXWS=false
export BUILD_CORBA=false
export BUILD_HOSTPOT=true
export BUILD_JDK=truegit
#要編譯的版本
export SKIP_DEBUG_BUILD=false
export SKIP_FASTDEBUG_BUILD=true
export DEBUG_NAME=debuggithub
#避免javaws和瀏覽器Java插件等的build
BUILD_DEPLOY=falseubuntu
#不build安裝包
BUILD_INSTALL=false瀏覽器
#包含所有的調試信息
export ENABLE_FULL_DEBUG_SYMBOLS=1
#調試信息是否壓縮,若是配置爲1,libjvm.debuginfo會被壓縮成libjvm.diz,將不能被debug。
export ZIP_DEBUGINFO_FILES=0
#用於編譯線程數
export HOTSPOT_BUILD_JOBS=3bash
#設置存放編譯結果的目錄
#export ALT_OUTPUTDIR=/home/ddy/openjdk/7/builddom
unset CLASSPATH
unset JAVA_HOME
make sanity
DEBUG_BINARIES=true make 2>&1
5.開始編譯 在openjdk目錄下,運行build.sh
bash
chmod +x build.sh
./build.sh
最後編譯耗時將近2分鐘。編譯完成輸出以下信息: ![compile-success][4] 此時openjdk就編譯完成了,編譯的輸出在``/home/ddy/openjdk-compile/openjdk-7u40-fcs-b43-26/openjdk/build/``下。 進入``/home/ddy/openjdk-compile/openjdk-7u40-fcs-b43-26/openjdk/build/linux-amd64-debug/j2re-image/bin n``,執行 ``./java -version`` 輸出的java版本信息將是帶着你的機器用戶名,個人輸出是:
bash
openjdk version "1.7.0-internal-debug"
OpenJDK Runtime Environment (build 1.7.0-internal-debug-ddy_2017_06_10_22_30-b00)
OpenJDK 64-Bit Server VM (build 24.0-b56-jvmg, mixed mode)
`# debug 編譯完成了以後,就能夠對JDK源碼和HotSpot源碼等進行debug了。 ## JDK 首先是JDK源碼,在build目錄下編譯生成的jdk裏面的jar包都是可編譯的了,直接把eclipse的JDK或者JRE換成編譯成功的JDK或者JRE便可。 ## HotSpot 注意,若是不能進入斷點,出現如下相似信息:
Missing separate debuginfo for/root/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/lib/amd64/server/libjvm.so``
是由於在編譯時由於編譯配置項不正確而沒有生成調試的符號信息,或生成後被壓縮爲"libjvm.diz"了,因此沒法找到。若是是由於沒有編譯時沒有生成調試信息,須要修改編譯配置並從新編譯。對於被壓縮的狀況,能夠去到"libjvm.so"所在目錄
若是在編譯時,把配置信息修改以下,則不會出現不能上述問題。
#包含所有的調試信息 export ENABLE_FULL_DEBUG_SYMBOLS=1 #調試信息是否壓縮,若是配置爲1,libjvm.debuginfo會被壓縮成libjvm.diz,將不能被debug。 export ZIP_DEBUGINFO_FILES=0
參考:CentOS上編譯OpenJDK8源碼 以及 在eclipse上調試HotSpot虛擬機源碼
生成要運行的JAVA類
首先在/home/ddy/src/java-src
目錄下創建要運行的FileChannelTest.java,這個類在寫文件時調用了JDK的native方法,其代碼以下:
```java
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class FileChannelTest {
public static void main(String[] args) throws IOException {
FileChannel channel=new RandomAccessFile("test.txt","rw").getChannel();
ByteBuffer buffer=ByteBuffer.allocate(1000);
channel.write(buffer);
}
}
而後對其進行編譯,運行:
bash
ddy@ddy-Aspire-V5-573G ~ $ cd src/java-src/
ddy@ddy-Aspire-V5-573G ~/src/java-src $ pwd
/home/ddy/src/java-src
ddy@ddy-Aspire-V5-573G ~/src/java-src $ /home/ddy/openjdk-compile/openjdk-7u40-fcs-b43-26/openjdk/build/linux-amd64-debug/j2sdk-image/bin/javac FileChannelTest.java
```
/home/ddy/openjdk-compile/openjdk-7u40-fcs-b43-26/openjdk/build/linux-amd64-debug/j2sdk-image/bin/java
(編譯生成的openjdk虛擬機入口)JAVA_HOME=/home/ddy/openjdk-compile/openjdk-7u40-fcs-b43-26/openjdk/build/linux-amd64-debug/j2sdk-image
(編譯生成JDK所在目錄)CLASSPATH=.:/home/ddy/src/java-src
(FileChannelTest.java文件所在目錄)而後開始debug。
首先是第一個斷點:
F8進行到下一個斷電點:
從上圖能夠看到,FileChannel.write()最後調用的是write()操做系統調用。
因此,你們如今能夠隨便debug HotSpot的源碼和JDK的native源碼了。酷!
openjdk之編譯常常出現的問題
openjdk8的編譯和debug
編譯主要參考:ubuntu14.04 編譯openjdk7
debug主要參考:CentOS上編譯OpenJDK8源碼 以及 在eclipse上調試HotSpot虛擬機源碼