缘起
【1】中我们已经在win10环境下编译了openjdk8, 下面就开始单步调试hotspot.
分析
关于jdk、jre、jvm 、Hotspot之间的联系和区别参见【2】
首先看看openjdk的源码包结构

1 | openjdk |
我们熟知的java的一些类就在D:\openjdk-8u40-src-b25-10_feb_2015\openjdk\jdk\src\share\classes中,例如java.util工具包

但是我们要看的其实并不是这些. 我们要看的是hotspot. 即D:\openjdk-8u40-src-b25-10_feb_2015\openjdk\hotspot 目录下
因为我们要做的事情是,使用hotspot执行一个class字节码文件. 我们关注的是这样一个过程. 而不是一个java源文件编译成class文件. 这里面具体的关系若有不清楚,参看【2】.
hotspot源码包路径是D:\openjdk-8u40-src-b25-10_feb_2015\openjdk\hotspot

解释如下

好像最新的源码结构中没有src\share\tools\launcher
【1】中我们最后编译出来了java.exe 在
D:\openjdk-8u40-src-b25-10_feb_2015\openjdk\build\windows-x86_64-normal-server-fastdebug\jdk\objs\java_objs 目录中有.
然后我们理解一下java.exe和虚拟机(即这里的hotspot)之间的关系.
hotspot是作为动态链接库(dll)的形式被 java.exe 载入的。java.exe 负责解析參数,载入虚拟机链接库,它须要调用虚拟机中的函数来完毕运行 Java 程序的功能。所以,你在HotSpot的源码中找不到启动的程序的 main 函数.
好了,言归正传,我们开始debug我们的hotspot源码.
创建hotspot的vs2010工程
cmd执行 D:\vs2010\VC\bin\amd64\vcvars64.bat,但是执行完毕此命令之后不要关闭cmd窗口,因为这里仅仅是修改了环境变量
编辑D:\openjdk-8u40-src-b25-10_feb_2015\openjdk\hotspot\make\windows\create.bat
修改142行为cygwin64的安装目录如下(依据你自己的cygwin64的安装目录进行修改)
1
if exist d:\cygwin64\bin set HOTSPOTMKSHOME=d:\cygwin64\bin
执行下面命令
1
2
3cd D:\openjdk-8u40-src-b25-10_feb_2015\openjdk\hotspot\make\windows
之后
create.bat D:\openjdk-8u40-src-b25-10_feb_2015\openjdk\jdk执行完毕之后,在D:\openjdk-8u40-src-b25-10_feb_2015\openjdk\hotspot\build中多了vs-amd64目录,里面就有了一个vs2010工程. 这个就是hotspot源码工程.
D:\openjdk-8u40-src-b25-10_feb_2015\openjdk\build\windows-x86_64-normal-server-fastdebug\jdk\bin 下找到java.diz,用WinRAR解压它,将解压出的java.pdb和java.map放进同级目录,也就是D:\openjdk-8u40-src-b25-10_feb_2015\openjdk\build\windows-x86_64-normal-server-fastdebug\jdk\bin 中. 这一步是为了调试同级目录下的java.exe
利用VS2010单步调试
vs2010打开 D:\openjdk-8u40-src-b25-10_feb_2015\openjdk\hotspot\build\vs-amd64\jvm.vcxproj
配置编译参数Compiler2 Fastdebug + X64
右键项目点击Properties. 选择Debugging之后配置如下三个参数
具体为
1
2
3
4
5
6
7
8
9
10
11Command为编译好的java.exe路径
D:\openjdk-8u40-src-b25-10_feb_2015\openjdk\build\windows-x86_64-normal-server-fastdebug\jdk\bin\java.exe
Environment 为编译好的jdk路径
JAVA_HOME=D:\openjdk-8u40-src-b25-10_feb_2015\openjdk\build\windows-x86_64-normal-server-fastdebug\jdk
Command Arguments为jvm参数
-XXaltjvm=$(TargetDir) -Dsun.java.launcher=gamma -Djava.class.path=D:\openjdk-8u40-src-b25-10_feb_2015\javacode Test
为了便于调试,准备一个Test.java 放进创建的路径D:\openjdk-8u40-src-b25-10_feb_2015\javacode,下面编写一个Test.java
1 | public class Test { |
然后打开cmd,使用D:\openjdk-8u40-src-b25-10_feb_2015\openjdk\build\windows-x86_64-normal-server-fastdebug\jdk\bin\javac.exe 对其进行编译得到Test.class.

注意上面配置的XXaltjvm参数中就有这个Test,其中我们使用了 -Djava.class.path 来指定class文件位置
添加断点 share\vm\runtime\thread.cpp,line 3305, create_vm

点击下面的按钮



于是就可以结合源码来学习jvm内部原理了.
参考
【1】https://yfsyfs.github.io/2019/07/11/Windows10%E4%B8%8B%E7%BC%96%E8%AF%91openjdk8/
v1.5.2