Win10:请将Win10专业版/企业版更新到最新版本,否则安装WSL特性可能会卡住。
WSL: Powershell中直接输入:dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
具体参考如下地址:
https://docs.microsoft.com/zh-cn/windows/wsl/install-win10Ubuntu: 在Microsoft Store里搜索Ubuntu,点击安装。(按照自己习惯的Linux系统下载就行,我这用的Ubuntu)然后就可以把Ubuntu当作一个普通的应用打开了,如下图。
VSCode:下载Visual Studio Code:
https://code.visualstudio.com/openjdk:下载openjdk8源码,jdk8调试起来比较麻烦,因为需要jdk7作为boot-jdk,而jdk7已经archive了,无法直接通过linux的包管理来安装,所以需要自己手动下载。jdk8源码:
http://openjdk.java.net/projects/jdk8/
https://download.java.net/openjdk/jdk8u41/ri/openjdk-8u41-src-b04-14_jan_2020.zipjdk7:
https://www.oracle.com/java/technologies/javase/javase7-archive-downloads.html
二、WSL内开发环境安装
打开 Ubuntu后,我们先建议一个空目录,然后把jdk相关文件复制到这里(/mnt/d就是windows的d盘):mkdir openjdkcp /mnt/d/Graviton/Downloads/jdk-7u80-linux-x64.tar.gz openjdk/cp /mnt/d/Graviton/Downloads/jdk-8u41-src-b04-14_jan_2020.zip openjdk/
用apt包管理命令直接下载所有相关的必要工具:
sudo apt install build-essential zip unzip libxext-dev libx11-dev libxrender-dev libxtst-dev libxt-dev libcups2-dev libfreetype6-dev libasound2-dev gdb
解压刚才复制的两个文件:
cd openjdktar -zxvf jdk-7u80-linux-x64.tar.gzunzip jdk-8u41-src-b04-14_jan_2020.zip
我们要把环境变量PATH加上刚才jdk7的位置:
vim ~/.profile
在末尾加上,然后wq!保存:
PATH="/home/graviton/openjdk/jdk1.7.0_80/bin:$PATH"
最后确认下java版本
java -version
可以看到:
到这里,我们大概完成了20%,接下来,为了能够让jdk8正确编译,我们需要把gcc降级到4.4版本,因为刚才默认安装的build-essential中默认安装的是最新版本的gcc,在新版本的gcc中,加强了对语法的检验标准,导致jdk8源码里大量编译报错。
gcc4.4的版本太老了,需要加点包源:vim /etc/apt/sources.list
在最后加上这两行:
deb http://dk.archive.ubuntu.com/ubuntu/ trusty main universedeb http://dk.archive.ubuntu.com/ubuntu/ trusty-updates main universe
wq!保存后,就可以安装gcc-4.4
sudo apt-get install gcc-4.4sudo apt-get install g++-4.4
成功安装好后,把4.4调成默认版本,最后的100表示优先级,数字越高优先级越高,默认是60:
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.4 100sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.4 100
刚才我们有注意到,我们安装的Linux内核版本是4.4的,jdk8的hotspot的编译文件里只有支持到3以下的版本。因此我们需要改动点文件,让系统支持4以上的版本。找到./hotspot/make/linux/Makefile文件,在里面搜索SUPPORTED_OS_VERSION,在最后加上“4%”
# We do not want people accidentally building on old systems (e.g. Linux 2.2.x,# Solaris 2.5.1, 2.6).# Disable this check by setting DISABLE_HOTSPOT_OS_VERSION_CHECK=ok.SUPPORTED_OS_VERSION = 2.4% 2.5% 2.6% 3% 4%OS_VERSION := $(shell uname -r)EMPTY_IF_NOT_SUPPORTED = $(filter $(SUPPORTED_OS_VERSION),$(OS_VERSION))
接下来,我们就可以开始正式编译jdk8了。
cd openjdkchmod +x ./configure./configure --with-debug-level=slowdebug --with-freetype-include=/usr/include/freetype2 --with-freetype-lib=/usr/lib/x86_64-linux-gnu
运行成功后可以看到这样的提示:
make all
如果严格按照上面的步骤来安装的话,我们最终会看到这么一个report:
cd build/linux-x86_64-normal-server-slowdebug/jdk/bin./java -version
(除此之外,我们还可以安装上其他需要的插件,比如C/C++ ,再按提示,点击“Install in WSL: Ubuntu"。)
点进去后,按照提示,我们可以建立wsl和VSCode的连接,如下图:至此我们准备工作都已经做完,我们可以开始尝试加断点,调试jdk和hotspot。
我们先随便写一段简单的java代码,比如:
# MainClass.javapublic class MainClass { public static void main(String[] args) { String a = System.getenv().get("JAVA_HOME"); System.out.println(a); }}
接着我们需要用javac把它编译成class文件,我们也可以直接用构建个maven项目,然后使用mvn clean compile来编译,然后记下target目录,后面需要用到。
接下来,我们回到VSCode,在菜单栏里点击Run->Add Configuration,在./.vscode文件夹下会生成一个launch.json文件,我们按下面,稍作修改:
// .vscode/launch.json{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/build/linux-x86_64-normal-server-slowdebug/jdk/bin/java", "args": ["-cp", "/mnt/d/codes/test/target/classes/", "MainClass"], "stopAtEntry": true, "cwd": "${workspaceFolder}", "environment": [ {"name": "JAVA_HOME", "value":"${workspaceFolder}/build/linux-x86_64-normal-server-slowdebug/jdk/bin"} ,{"name": "LD_LIBRARY_PATH","value": "${workspaceFolder}/build/linux-x86_64-normal-server-slowdebug/jdk/lib/amd64"}], "externalConsole": false, "MIMode": "gdb", "miDebuggerPath": "/usr/bin/gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ] } ]}
说明下这个配置文件里几个关键字段的意义:
- type:使用dbg来做调试工具
- program:执行程序的路径,这里就是我们编译好的java
- args:传给program的参数,结合命令行,就是java的启动命令。结合上面的例子,实际就是在Terminal里输入下面这段: java -cp /mnt/d/codes/test/target/classes/ MainClass
- environment: 添加环境变量
- miDebuggerPath: 指定调试工具gdb在wsl里的绝对路径
然后我们就可以点击左侧第四个按钮,然后点击上面绿色的启动按钮""
我们接下来,找到hotspot/src/share/vm/prims/jni.cpp文件,搜索JNI_CreateJavaVM方法,这个hotspot虚拟机创建的入口方法,在它下面加个断点,继续支持,你会发现并不能命中这个断点,这是因为还缺少一个hotspot的debuginfo。
我们继续回到wsl,执行下面的命令:
unzip ./build/linux-x86_64-normal-server-slowdebug/jdk/lib/amd64/server/libjvm.diz
我们再回来VSCode调试,我们就可以正常命中hotspot的入口方法了。