CLion调试OpenJDK12—Windows 11系统
编译OpenJDK12见文章:编译OpenJDK12——Windows 11系统
前言:
- 提前要将环境准备好:
Windows环境运行Linux命令——Cygwin安装:https://blog.csdn.net/qq_43460743/article/details/129140355
Microsoft Visual Studio C++2017+Windows 11 SDK环境:https://blog.csdn.net/qq_43460743/article/details/129141150
编译OpenJDK12——Windows 11系统:https://blog.csdn.net/qq_43460743/article/details/129139741
MinGW Make CMake安装使用 —Windows 11系统:https://blog.csdn.net/qq_43460743/article/details/129203048
CLion 2022安装配置环境—Windows 11系统:https://blog.csdn.net/qq_43460743/article/details/129202435 - 视频演示:
1.调试JDK代码
在本次实战里,笔者采用的IDE是JetBrains的CLion 2022.3.2,读者可以在JetBrains网站(官网地址:https://www.jetbrains.com/clion/)上直接下载,环境配置见:CLion 2022安装配置环境—Windows 11系统。
打开CLion,选择New Project。
选择新建一个C Executable,Location选择jdk12源码目录,Language standard选择C99标准,点击创建Create。
选择Open Project,等待Scanning Files to Index。CLion 2022 C++运行环境有MinGW、Cygwin与Visual Studio三种,环境配置见CLion 2022安装配置环境—Windows 11系统。
调试代码前需要配置构建目标,Settings->Build,Execution,Deployment-> Custom Build Targets构建Build。
Create Tool配置含义:
构建Clean。
Create Tool配置含义:
配置结束,点击保存OK。
Toolchain一定要选择Visual Studio工具链,因为OpenJDk是在Visual Studio中编译完成的。
保存好后,点击右上角Add Configuration。
配置一个Custom Build Application命名为DebugJavaVersion,红色框内的Build记得将它移除掉。
在java.c(jdk12\src\java.base\share\native\libjli\java.c)代码的JavaMain函数下面打断点。
打开java.h头文件,可以看到并没有报错误无法找到头文件。
点击刚刚创建的DebugJavaVersion在Debug模式下测试运行,程序会停止在JavaMain函数的断点下。
F9跳过断点,程序调试完毕。
2.调试Java代码
1)测试执行.java文件,在当前编译器中(jdk12根目录)创建一个java目录用来存放测试java文件。
import java.util.concurrent.locks.LockSupport;
public class Demo {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("thread run... ...");
});
System.out.println("Hello, I'am JDK 12!.");
thread.start();
LockSupport.park();
}
}
编写Java代码时如果找不到Java函数所在的包路径,可以借助于IEDA(Java编译器)编写好代码后在复制到CLion编译器中。
点击右上角Edit configurations配置一个新的Custom Build Application(删除红框处的Build)命名为JavaClassDemo,用来运行刚刚编写的Java代码。
JDK12直接执行java命令就可以直接执行.java文件。
Demo.java测试代码中调用LockSupport.park()函数,该方法会再调用Unsafe.park()这个native函数,这个native函数在unsafe.cpp(jdk12\src\hotspot\share\prims\unsafe.cpp)中定义,在unsafe.cpp中搜索Unsafe_Park()函数,在函数内设置断点。
Debug模式启动JavaClassDemo,跟踪测试Java代码。
程序停止在了unsafe.cpp断点处,左边点击Unsafe_Park()函数位置,在Variables处输入env可以看见环境信息。
F9跳过断点,在Console(Console紧挨着Debugger)中输出System.out.println信息。
2)JDK1.8及以下的版本执行.java文件需要先编译成.class文件,然后再执行.class文件,JDK11、JDK12直接执行java命令就可以直接执行.java文件,其它版本笔者未做测试(意义不大)。
Demo.java文件编译成.class文件后再执行的过程,可以在编译器中做配置。点击右上角Edit configurations配置一个新的Custom Build Application(删除红框处的Build)命名为JavaCompileDemo,用来编译运行Demo.java代码。
java Demo命令表示执行一个Demo.class的文件,但是在工作目录D:\JetBrains\CLion\jdk12\java\下面只有一个Demo.java文件,现在需要在执行java Demo命令之前先编译好Demo.class文件,在Before launch处点击加号,创建一个Run External Tool用来编译Demo.java文件。
javac.exe在jdk12\build\windows-x86_64-server-fastdebug\jdk\bin目录下面,读者根据自己编译的jdk参照选择路径。
记得删除原有的Build。
在Debug模式下运行JavaCompileDemo,CLion首先会在D:\JetBrains\CLion\jdk12\java目录(Demo.java所在目录)下面编译生成Demo.class文件,然后执行编译后的Demo.class文件。
执行结果与直接执行Demo.java一致。
3).java与.class文件均测试完毕,接下来测试.jar程序包,原理与前面的测试是一样的。打开IDEA(Java编译器)将刚才的代码打包成jar包(提前要创建好maven工程),IDEA的使用方式不是这里讨论的重点,能读到这里的一定都不是等闲之辈,Java的编码功底也早已炉火纯青,IDEA的运用也只是小菜一碟了。
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bemyself</groupId>
<artifactId>jdk12</artifactId>
<version>1.0-THEPREVIOUSME</version>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.bemyself.jdk.Demo</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>assembly</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
将构建好的jar包复制到Demo.java同级目录下面(D:\JetBrains\CLion\jdk12\java),打开CLion点击右上角Edit configurations配置一个新的Custom Build Application(删除Build)命名为JavaRunJar,运行jar包(笔者将jar包重命名为Demo.jar)。
Debug模式下运行JavaRunJar··· ···
执行结果与直接执行Demo.java一致,至此对JDK的调试环境构建完毕。
下述摘自《深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)周志明》第一章1.7小节。
读者在调试Java代码执行时,如果要跟踪具体Java代码在虚拟机中是如何执行的,一开始可能会觉得有些无处入手,因为目前HotSpot在主流的操作系统上,都采用模板解释器来执行字节码,它与即时编译器一样,最终执行的汇编代码都是运行期间产生的,无法直接设置断点,所以HotSpot增加了以下参数来方便开发人员调试解释器:-XX:+TraceBytecodes -XX:StopInterpreterAt=<n>
这组参数的作用是当遇到序号为<n>的字节码指令时,便会中断程序执行,进入断点调试。调试解释器部分代码时,把这两个参数加到java命令的参数后面即可。
完成以上配置之后,一个可修改、编译、调试的HotSpot工程就完全建立起来了,HotSpot虚拟机启动器的执行入口是java.c的JavaMain()方法,读者可以设置断点单步跟踪。
参考
Saleson:https://blog.csdn.net/Mr_rain/article/details/123887310
xiaoye biog:https://www.cnblogs.com/xiaoye-2018/articles/15813470.html