ubuntu vscode_基于Win10新特性WSL+VSCode调试Hotspot虚拟机

Microsoft这几年在不断拥抱开源,拥抱开发者社区。除了收购github外,它在Win10中加入了新特性WSL(Windows Sub-System for Linux),这使得开发者真正有机会在享受Windows PC的便利同时,又能有机会有一套真正意义上 (在此之前的选择主要是Cygwin)基于Linux内核的开发系统环境。同时,同时我觉得Visual Studio Code(VSCode)也是最近几年微软颠覆自我的一个IDE工具,它能以轻量级、插件化的形式可以适配到任何语言的开发。做过.NET开发的同学都知道几代Visual Studio工具都是非常重的IDE,安装更新都要几个小时,虽然功能齐全,但也仅仅局限在微软自己的生态中。而Visual Studio Code的出现也体现出微软意识到固步自封的局限性。我个人觉得,目前VSCode在Java、Python等语言的开发上还比不上Jetbrains的IDE,但未来可期。为此,我花了几个周末时间,尝试基于WSL+VSCode来调试一把hotspot虚拟机,整理出来分享给大家。 一、准备工作
  1. Win10:请将Win10专业版/企业版更新到最新版本,否则安装WSL特性可能会卡住。

  2. WSL: Powershell中直接输入:dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart 
    具体参考如下地址:
    https://docs.microsoft.com/zh-cn/windows/wsl/install-win10

  3. Ubuntu: 在Microsoft Store里搜索Ubuntu,点击安装。(按照自己习惯的Linux系统下载就行,我这用的Ubuntu)然后就可以把Ubuntu当作一个普通的应用打开了,如下图。254949d384945b933fc52c96a98058ce.png58aa4671026df7a952f2785d09fe0872.png

  4.  VSCode:下载Visual Studio Code:
    https://code.visualstudio.com/

  5. 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
可以看到:

b65a3e26ab75714157a4d536c2d3f09d.png

到这里,我们大概完成了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
运行成功后可以看到这样的提示:

ba1126cb007a6083c283d520f93ac5aa.png

接下来我们可以正式编译了:
make all
如果严格按照上面的步骤来安装的话,我们最终会看到这么一个report:

d88a44ae82ab9a67c56c456341b89cfc.png

最后,我们可以验证下debug版的java是否成功:
cd build/linux-x86_64-normal-server-slowdebug/jdk/bin./java -version

be304a746c54418343ed831c65fb6dc1.png

三、VSCode的安装和配置到此,我们完成了50%,我们下面转到VSCode上。在VSCode的左边最后一个模块,搜索安装"Remote - WSL"插件,然后就能看到如下图的倒数第二个按钮。

7fe9eee68ceebab64bc42ceccd87492a.png

(除此之外,我们还可以安装上其他需要的插件,比如C/C++ ,再按提示,点击“Install in WSL: Ubuntu"。)

点进去后,按照提示,我们可以建立wsl和VSCode的连接,如下图:

5b4f1807c820d98445b090fd5511f216.png

然后点击左侧第一个按钮,我们就能看到刚才我们解压和编译后的文件夹:

252876422089d3fb7fdc3dc1551cdacb.png

四、开始调试

至此我们准备工作都已经做完,我们可以开始尝试加断点,调试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里的绝对路径

然后我们就可以点击左侧第四个按钮,然后点击上面绿色的启动按钮""

aaddcac9472e05b6329244b60b9b4c3e.png

我们可以看到断点停在Java的main函数入口:

c6df702c2d5634a226e6362c595929d1.png

(jdk/src/share/bin/main.c)

我们接下来,找到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的入口方法了。

9ee257f11e1b6d67ddecd3a37fee54c0.png

最后执行完成后,在TERMINAL里可以看到我们Java代码打印出来的环境变量JAVA_HOME。

53a4a4b7b966d32454ff1d2d7f5e6961.png

至此,我们可以欢快地开启在Windows上探索 Java核心实现代码的旅程 了 。 (PS:我用Cygwin也成功跑完了整个流程,只是需要改了很多源文件,不够纯粹,不太适合当开发环境来用。)

329cbb98e1ade1d3aabbc26875b4e608.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值