原本想在 Windows 下編譯調試,但過程中遇到了諸多錯誤(老是報路徑錯誤。。。),最后只好放棄。
此次記錄調試的方法為 CentOS7 上編譯,Windows 上使用 Clion 遠程調試(也可直接在 CentOS7 桌面環境直接調試,速度快)。
一、下載源碼(OpenJDK8)
yum 源使用的是阿里的 https://opsx.alibaba.com/mirror?lang=zh-CN
這里使用 mercurial(類似 Git 的版本控制系統) 下載源碼,方便更新。
下面網址可以下載 mercurial 較新的版本。
https://mercurial.selenic.com/wiki/ChineseDownload
https://www.mercurial-scm.org/wiki/Download
# 或者 yum install hg -y yum install mercurial -y # 下載源碼,目標目錄需要為空 hg clone http://hg.openjdk.java.net/jdk8u/jdk8u /opt/jdk8u # 更新代碼,操作和 Git 類似 hg pull # 獲取完整源碼(需要在源碼目錄下執行,下載時間較長,一次可能下載不成功,多試幾次) cd /opt/jdk8u/ sh get_source.sh # 完全下載成功的打印信息。若輸出中出現回滾字樣,即代表下載過程中出錯了,需重新執行下載腳本 No repositories to process. # Repositories: . corba jaxp jaxws langtools jdk hotspot nashorn .: cd . && hg pull -u corba: cd corba && hg pull -u jaxp: cd jaxp && hg pull -u jaxws: cd jaxws && hg pull -u langtools: cd langtools && hg pull -u jdk: cd jdk && hg pull -u hotspot: cd hotspot && hg pull -u nashorn: cd nashorn && hg pull -u .: 正在拉自 http://hg.openjdk.java.net/jdk8u/jdk8u/ corba: 正在拉自 http://hg.openjdk.java.net/jdk8u/jdk8u/corba jaxp: 正在拉自 http://hg.openjdk.java.net/jdk8u/jdk8u/jaxp jaxws: 正在拉自 http://hg.openjdk.java.net/jdk8u/jdk8u/jaxws jdk: 正在拉自 http://hg.openjdk.java.net/jdk8u/jdk8u/jdk langtools: 正在拉自 http://hg.openjdk.java.net/jdk8u/jdk8u/langtools hotspot: 正在拉自 http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot nashorn: 正在拉自 http://hg.openjdk.java.net/jdk8u/jdk8u/nashorn corba: 正在搜索修改 corba: 沒有發現修改 jdk: 正在搜索修改 jdk: 沒有發現修改 jaxws: 正在搜索修改 jaxws: 沒有發現修改 .: 正在搜索修改 .: 沒有發現修改 langtools: 正在搜索修改 langtools: 沒有發現修改 hotspot: 正在搜索修改 hotspot: 沒有發現修改 jaxp: 正在搜索修改 jaxp: 沒有發現修改 nashorn: 正在搜索修改 nashorn: 沒有發現修改
這里手動執行多次比較麻煩,自己寫了個小腳本,循環執行。
#!/bin/bash for i in {1..28} do cd /opt/jdk8u/; sh ./get_source.sh; done
二、編譯源碼
Linux 下編譯比 Windows 下簡單太多。
https://hg.openjdk.java.net/jdk/jdk/file/tip/doc/building.md
https://hg.openjdk.java.net/jdk8u/jdk8u/raw-file/tip/README-builds.html
構建 JDK 8 需要使用 Update 7 或更高版本的 JDK 7 版本。JDK 8 開發人員不應使用 JDK 8 作為引導 JDK,以確保 JDK 8 依賴關系不會引入使用 JDK 7 構建的系統部分。
# 查詢 yum list installed | grep jdk rpm -qa | grep jdk # 卸載 yum remove -y xxxxxxx # 驗證 java -version # -bash: java: 未找到命令 # 安裝 JDK7 # https://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase7-521261.html tar -zxf jdk-7u80-linux-x64.tar.gz -C /opt/
配置
cd /opt/jdk8u/ chmod +x configure # 直接執行配置,看看缺少什么工具或參數,按照錯誤提示安裝和添加參數即可 ./configure # 安裝編譯所需工具包 yum install -y unzip zip libXtst-devel libXt-devel libXrender-devel cups-devel freetype-devel alsa-lib-devel fontconfig-devel yum groupinstall -y "Development Tools" # 配置編譯環境 ./configure --with-boot-jdk=/opt/jdk1.7.0_80/ --with-debug-level=slowdebug --with-native-debug-symbols=internal # --with-debug-level=slowdebug 輸出更多調試信息 # --with-native-debug-symbols=internal 內鏈方式生成調試鏈接符號(可執行文件與源代碼的對應關系) # 生成調試鏈接符號還有以下方式,相當於 --enable-debug-symbols --disable-zip-debug-info # ZIP_DEBUGINFO_FILES=0 生成調試信息文件 libjvm.debuginfo,否則會被壓縮成 libjvm.diz,debug 時只能看到匯編代碼,不能跟進源碼 # ENABLE_FULL_DEBUG_SYMBOLS=1 生成調試符號,可不加,不影響調試 ##################################### 配置生產成功打印信息 ################################# A new configuration has been successfully created in /opt/jdk8u/build/linux-x86_64-normal-server-release using configure arguments '--with-boot-jdk=/opt/jdk1.7.0_80/ --with-debug-level=slowdebug --with-native-debug-symbols=internal'. Configuration summary: * Debug level: release * JDK variant: normal * JVM variants: server * OpenJDK target: OS: linux, CPU architecture: x86, address length: 64 Tools summary: * Boot JDK: java version "1.7.0_80" Java(TM) SE Runtime Environment (build 1.7.0_80-b15) Java HotSpot(TM) 64-Bit Server VM (build 2 4.80-b11, mixed mode) (at /opt/jdk1.7.0_80) * Toolchain: gcc (GNU Compiler Collection) * C Compiler: Version 4.8.5 (at /usr/bin/gcc) * C++ Compiler: Version 4.8.5 (at /usr/bin/g++) Build performance summary: * Cores to use: 7 * Memory limit: 15884 MB WARNING: The result of this configuration has overridden an older configuration. You *should* run 'make clean' to make sure you get a proper build. Failure to do so might result in strange build problems.
configure 幫助文檔

Running generated-configure.sh `configure' configures OpenJDK jdk8 to adapt to many kinds of systems. Usage: /opt/jdk8u/configure [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print `checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for `--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or `..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [/usr/local] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, `make install' will install all the files in `/usr/local/bin', `/usr/local/lib' etc. You can specify an installation prefix other than `/usr/local' using `--prefix', for instance `--prefix=$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/openjdk] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] X features: --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-openjdk-only suppress building custom source even if present [disabled] --enable-debug set the debug level to fastdebug (shorthand for --with-debug-level=fastdebug) [disabled] --disable-headful disable building headful support (graphical UI support) [enabled] --enable-hotspot-test-in-build run the Queens test after Hotspot build [disabled] --enable-unlimited-crypto Enable unlimited crypto policy [disabled] --disable-debug-symbols disable generation of debug symbols [enabled] --disable-zip-debug-info disable zipping of debug-info files [enabled] --enable-macosx-runtime-support Deprecated. Option is kept for backwards compatibility and is ignored --disable-freetype-bundling disable bundling of the freetype library with the build result [enabled on Windows or when using --with-freetype, disabled otherwise] --enable-sjavac use sjavac to do fast incremental compiles [disabled] --disable-precompiled-headers disable using precompiled headers when compiling C++ [enabled] --enable-ccache enable using ccache to speed up recompilations [disabled] Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-custom-make-dir use this directory for custom build/make files --with-target-bits build 32-bit or 64-bit binaries (for platforms that support it), e.g. --with-target-bits=32 [guessed] --with-jdk-variant JDK variant to build (normal) [normal] --with-jvm-interpreter JVM interpreter to build (template, cpp) [template] --with-jvm-variants JVM variants (separated by commas) to build (server, client, minimal1, kernel, zero, zeroshark, core) [server] --with-debug-level set the debug level (release, fastdebug, slowdebug) [release] --with-devkit use this devkit for compilers, tools and resources --with-sys-root alias for --with-sysroot for backwards compatability --with-sysroot use this directory as sysroot) --with-tools-dir alias for --with-toolchain-path for backwards compatibility --with-toolchain-path prepend these directories when searching for toolchain binaries (compilers etc) --with-extra-path prepend these directories to the default path --with-xcode-path explicit path to Xcode 4 (generally for building on 10.9 and later) --with-conf-name use this as the name of the configuration [generated from important configuration options] --with-builddeps-conf use this configuration file for the builddeps --with-builddeps-server download and use build dependencies from this server url --with-builddeps-dir store downloaded build dependencies here [/localhome/builddeps] --with-builddeps-group chgrp the downloaded build dependencies to this group --with-cacerts-file specify alternative cacerts file --with-milestone Set milestone value for build [internal] --with-update-version Set update version value for build [b00] --with-user-release-suffix Add a custom string to the version string if build number isn't set.[username_builddateb00] --with-build-number Set build number value for build [b00] --with-vendor-name Set vendor name. Among others, used to set the 'java.vendor' and 'java.vm.vendor' system properties. [not specified] --with-vendor-url Set the 'java.vendor.url' system property [not specified] --with-vendor-bug-url Set the 'java.vendor.url.bug' system property [not specified] --with-vendor-vm-bug-url Sets the bug URL which will be displayed when the VM crashes [not specified] --with-copyright-year Set copyright year value for build [current year] --with-boot-jdk path to Boot JDK (used to bootstrap build) [probed] --with-boot-jdk-jvmargs specify JVM arguments to be passed to all invocations of the Boot JDK, overriding the default values, e.g --with-boot-jdk-jvmargs="-Xmx8G -enableassertions" --with-add-source-root for each and every source directory, look in this additional source root for the same directory; if it exists and have files in it, include it in the build --with-override-source-root for each and every source directory, look in this override source root for the same directory; if it exists, use that directory instead and ignore the directory in the original source root --with-adds-and-overrides use the subdirs 'adds' and 'overrides' in the specified directory as add-source-root and override-source-root --with-override-langtools use this langtools dir for the build --with-override-corba use this corba dir for the build --with-override-jaxp use this jaxp dir for the build --with-override-jaxws use this jaxws dir for the build --with-override-hotspot use this hotspot dir for the build --with-override-nashorn use this nashorn dir for the build --with-override-jdk use this jdk dir for the build --with-import-hotspot import hotspot binaries from this jdk image or hotspot build dist dir instead of building from source --with-toolchain-type the toolchain type (or family) to use, use '--help' to show possible values [platform dependent] --with-toolchain-version the version of the toolchain to look for, use '--help' to show possible values [platform dependent] --with-jtreg Regression Test Harness [probed] --with-extra-cflags extra flags to be used when compiling jdk c-files --with-extra-cxxflags extra flags to be used when compiling jdk c++-files --with-extra-ldflags extra flags to be used when linking jdk --with-native-debug-symbols set the native debug symbol configuration (none, internal, external, zipped) [varying] --with-x use the X Window System --with-cups specify prefix directory for the cups package (expecting the headers under PATH/include) --with-cups-include specify directory for the cups include files --with-freetype specify prefix directory for the freetype package (expecting the libraries under PATH/lib and the headers under PATH/include) --with-freetype-include specify directory for the freetype include files --with-freetype-lib specify directory for the freetype library --with-freetype-src specify directory with freetype sources to automatically build the library (experimental, Windows-only) --with-alsa specify prefix directory for the alsa package (expecting the libraries under PATH/lib and the headers under PATH/include) --with-alsa-include specify directory for the alsa include files --with-alsa-lib specify directory for the alsa library --with-fontconfig specify prefix directory for the fontconfig package (expecting the headers under PATH/include) --with-fontconfig-include specify directory for the fontconfig include files --with-giflib use giflib from build system or OpenJDK source (system, bundled) [bundled] --with-zlib use zlib from build system or OpenJDK source (system, bundled) [bundled] --with-stdc++lib=<static>,<dynamic>,<default> force linking of the C++ runtime on Linux to either static or dynamic, default is static with dynamic as fallback --with-msvcr-dll path to microsoft C runtime dll (msvcr*.dll) (Windows only) [probed] --with-msvcp-dll path to microsoft C++ runtime dll (msvcp*.dll) (Windows only) [probed] --with-ucrt-dll-dir path to Microsoft Windows Kit UCRT DLL dir (Windows only) [probed] --with-dxsdk Deprecated. Option is kept for backwards compatibility and is ignored --with-dxsdk-lib Deprecated. Option is kept for backwards compatibility and is ignored --with-dxsdk-include Deprecated. Option is kept for backwards compatibility and is ignored --with-num-cores number of cores in the build system, e.g. --with-num-cores=8 [probed] --with-memory-size memory (in MB) available in the build system, e.g. --with-memory-size=1024 [probed] --with-jobs number of parallel jobs to let make run [calculated based on cores and memory] --with-sjavac-server-java use this java binary for running the sjavac background server [Boot JDK java] --with-ccache-dir where to store ccache files [~/.ccache] Some influential environment variables: BASENAME Override default value for BASENAME BASH Override default value for BASH CAT Override default value for CAT CHMOD Override default value for CHMOD CMP Override default value for CMP COMM Override default value for COMM CP Override default value for CP CUT Override default value for CUT DATE Override default value for DATE DIFF Override default value for DIFF DIRNAME Override default value for DIRNAME ECHO Override default value for ECHO EXPR Override default value for EXPR FILE Override default value for FILE FIND Override default value for FIND HEAD Override default value for HEAD LN Override default value for LN LS Override default value for LS MKDIR Override default value for MKDIR MKTEMP Override default value for MKTEMP MV Override default value for MV NAWK Override default value for NAWK PRINTF Override default value for PRINTF RM Override default value for RM SH Override default value for SH SORT Override default value for SORT TAIL Override default value for TAIL TAR Override default value for TAR TEE Override default value for TEE TOUCH Override default value for TOUCH TR Override default value for TR UNAME Override default value for UNAME UNIQ Override default value for UNIQ WC Override default value for WC WHICH Override default value for WHICH XARGS Override default value for XARGS AWK Override default value for AWK GREP Override default value for GREP EGREP Override default value for EGREP FGREP Override default value for FGREP SED Override default value for SED CYGPATH Override default value for CYGPATH READLINK Override default value for READLINK DF Override default value for DF SETFILE Override default value for SETFILE CPIO Override default value for CPIO UNZIP Override default value for UNZIP ZIP Override default value for ZIP LDD Override default value for LDD READELF Override default value for READELF HG Override default value for HG STAT Override default value for STAT TIME Override default value for TIME DSYMUTIL Override default value for DSYMUTIL XATTR Override default value for XATTR CODESIGN Override default value for CODESIGN PKG_CONFIG path to pkg-config utility CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a nonstandard directory <lib dir> LIBS libraries to pass to the linker, e.g. -l<library> CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if you have headers in a nonstandard directory <include dir> CXX C++ compiler command CXXFLAGS C++ compiler flags CPP C preprocessor CXXCPP C++ preprocessor AS Override default value for AS AR Override default value for AR OBJC Objective C compiler command OBJCFLAGS Objective C compiler flags LIPO Override default value for LIPO STRIP Override default value for STRIP NM Override default value for NM GNM Override default value for GNM MCS Override default value for MCS OBJCOPY Override default value for OBJCOPY OBJDUMP Override default value for OBJDUMP BUILD_CC Override default value for BUILD_CC BUILD_CXX Override default value for BUILD_CXX BUILD_LD Override default value for BUILD_LD JTREGEXE Override default value for JTREGEXE XMKMF Path to xmkmf, Makefile generator for X Window System FREETYPE_CFLAGS C compiler flags for FREETYPE, overriding pkg-config FREETYPE_LIBS linker flags for FREETYPE, overriding pkg-config ALSA_CFLAGS C compiler flags for ALSA, overriding pkg-config ALSA_LIBS linker flags for ALSA, overriding pkg-config LIBFFI_CFLAGS C compiler flags for LIBFFI, overriding pkg-config LIBFFI_LIBS linker flags for LIBFFI, overriding pkg-config CCACHE Override default value for CCACHE Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to <build-dev@openjdk.java.net>. OpenJDK home page: <http://openjdk.java.net>. Additional (non-autoconf) OpenJDK Options: --openjdk-target=TARGET cross-compile with TARGET as target platform (i.e. the one you will run the resulting binary on). Equivalent to --host=TARGET --target=TARGET --build=<current platform> --debug-configure Run the configure script with additional debug logging enabled. The following toolchains are available as arguments to --with-toolchain-type. Which are valid to use depends on the build platform. gcc GNU Compiler Collection clang clang/LLVM solstudio Oracle Solaris Studio xlc IBM XL C/C++ microsoft Microsoft Visual Studio Please be aware that, when cross-compiling, the OpenJDK configure script will generally use 'target' where autoconf traditionally uses 'host'. Also note that variables must be passed on the command line. Variables in the environment will generally be ignored, unlike traditional autoconf scripts.
編譯
make images JOBS=8 # 編譯成功打印信息 ----- Build times ------- Start 2019-06-27 01:22:28 End 2019-06-27 01:31:44 00:00:20 corba 00:00:09 demos 00:01:53 docs 00:03:01 hotspot 00:00:17 images 00:00:18 jaxp 00:00:23 jaxws 00:02:06 jdk 00:00:34 langtools 00:00:15 nashorn 00:09:16 TOTAL ------------------------- Finished building OpenJDK for target 'all' # 測試 ./build/linux-x86_64-normal-server-release/jdk/bin/java -version # openjdk version "1.8.0-internal" # OpenJDK Runtime Environment (build 1.8.0-internal-root_2019_06_27_00_56-b00) # OpenJDK 64-Bit Server VM (build 25.71-b00, mixed mode) # 查看 libjvm.debuginfo ls ./build/linux-x86_64-normal-server-release/jdk/lib/amd64/server/ # 若編譯時沒有設置生成,可進入該目錄(libjvm.so 所在目錄)手動解壓 unzip libjvm.diz
make 幫助文檔

OpenJDK Makefile help ===================== Common make targets . make [default] # Compile all product in langtools, hotspot, jaxp, jaxws, corba and jdk . make all # Compile everything, all repos and images . make images # Create complete j2sdk and j2re images . make docs # Create javadocs . make overlay-images # Create limited images for sparc 64 bit platforms . make profiles # Create complete j2re compact profile images . make bootcycle-images # Build images twice, second time with newly build JDK . make install # Install the generated images locally . make clean # Remove all files generated by make, but not those generated by configure . make dist-clean # Remove all files, including configuration . make help # Give some help on using make . make test # Run tests, default is all tests (see TEST below) Targets for specific components (Component is any of langtools, corba, jaxp, jaxws, hotspot, jdk, nashorn, images, overlay-images, docs or test) . make <component> # Build <component> and everything it depends on. . make <component>-only # Build <component> only, without dependencies. This is faster but can result in incorrect build results! . make clean-<component> # Remove files generated by make for <component> Useful make variables . make CONF= # Build all configurations (note, assignment is empty) . make CONF=<substring> # Build the configuration(s) with a name matching <substring> . make LOG=<loglevel> # Change the log level from warn to <loglevel> Available log levels are: 'warn' (default), 'info', 'debug' and 'trace' To see executed command lines, use LOG=debug . make JOBS=<n> # Run <n> parallel make jobs Note that -jN does not work as expected! . make test TEST=<test> # Only run the given test or tests, e.g. make test TEST="jdk_lang jdk_net"
三、Windows 遠程調試
CentOS7 端
yum remove -y cmake gdb yum install -y gcc gcc-c++ make wget # 安裝 cmake,yum 源安裝的版本較低 cd /opt/ wget https://cmake.org/files/v3.14/cmake-3.14.5.tar.gz tar -zxf cmake-3.14.5.tar.gz cd cmake-3.14.5 # 默認安裝在 /usr/local/share/,可執行文件在 /usr/local/bin/ ./bootstrap && make && make install ln -s /usr/local/bin/cmake /usr/bin/cmake cmake -version # 安裝 gdb # 這里可以找到 gdb 鏡像站點 https://www.gnu.org/software/gdb/download/ # 這里下載 texinfo 新版本 http://ftp.gnu.org/gnu/texinfo/ yum install -y texinfo cd /opt/ wget https://mirrors.ustc.edu.cn/gnu/gdb/gdb-8.2.1.tar.gz tar -zxf gdb-8.2.1.tar.gz cd gdb-8.2.1 # 之前若出現過編譯錯誤需要刪掉(有緩存),重新解壓編譯 # 默認安裝在 /usr/local/share/,可執行文件在 /usr/local/bin/ ./configure && make && make install ln -s /usr/local/bin/gdb /usr/bin/gdb gdb -ver
Windows 端
首先用 Clion 新建一個空項目
遠程調試
同步代碼(windows 上的代碼需要和 CentOS 上的代碼一樣)
連接信息
對應目錄,本地目錄為新建的 Hello World 項目路徑
同步時要排除的本地目錄
下載遠程代碼
關閉項目,用載入的方式重新打開項目
設置遠程調試,地址為 CentOS 地址,端口隨意
在 CentOS 上啟動 GDB,端口與上面對應
yum install gdb-gdbserver -y gdbserver :1234 /opt/jdk8u/build/linux-x86_64-normal-server-release/jdk/bin/java -version
打上斷點,啟動的 DeBug(比較慢,載入 libjvm.debuginfo 的時候)
四、CentOS 桌面本地調試
只調試 JVM 可以直接導入 hotspot 項目,速度快點
配置調試
忽略調試時的 SIGSEGV 信號,在用戶目錄新建 .gdbinit 文件
handle SIGSEGV pass noprint nostop
https://blog.csdn.net/tjiyu/article/details/53725247
https://my.oschina.net/u/3982963/blog/3045233
https://www.jianshu.com/p/ee7e9176632c
https://yddmax.github.io/2017/06/11/openjdk7%E4%B9%8B%E7%BC%96%E8%AF%91%E5%92%8Cdebug/