OpenJDK-调试 (CLion)

导入项目

1、openjdk 12及以上版本

openjdk-12及以上的版本可以采用compile_commands.json导入,这种方式导入可以解决clion采用生成CMakeLists.txt而部分openjdk源码出现头文件无法找到的问题 JetBrains关于Compilation DataBase的介绍:https://blog.jetbrains.com/clion/2020/03/openjdk-with-clion/

1.1 生成compile-commands.json

在openjdk源码根目录执行make命令,本文档中采用openjdk-16

# 进入openjdk源码根目录
$ cd /Users/saleson/c-projects/jdk-jdk-16-ga 

# 生成compile-commands.json
$ make compile-commands
Compiling ......
Compiling 949 files for jdk.hotspot.agent
Updating compile_commands.json
Stopping sjavac server
Finished building target 'compile-commands' in configuration 'macosx-x86_64-server-slowdebug'

# 或者添加CONF参数,任意一个make命令执行成功即可
$ make CONF=macosx-x86_64-normal-server-slowdebug compile-commands

执行完成后,在{openjdk rootdir}/build/macosx-x86_64-normal-server-slowdebug目标下会生成一个compile-commans.json

$ pwd
/Users/saleson/c-projects/jdk-jdk-16-ga/build/macosx-x86_64-server-slowdebug
$ ls compile_commands.json
compile_commands.json

1.2 CLion通过compile_commands.json导入openjdk源码

打开CLion,操作路径: File > Open > 选择文件

/Users/saleson/c-projects/jdk-jdk-16-ga/build/macosx-x86_64-server-slowdebug/compile_commands.json

点击 open as Project 按钮
OpenJDK-调试 (CLion)
之后CLion会做扫描和index,但是这时候还看不到源码相关的文件和目录,因为此时根目录是/Users/saleson/c-projects/jdk-jdk-16-ga/build/macosx-x86_64-server-slowdebug, 需要更改项目根目录。
操作路径:Tools -> Compilation Database -> Change Project Root
选中openjdk的源码根目录,本文档中的源码根目录是/Users/saleson/c-projects/jdk-jdk-16-ga
CLion再次扫描文件和建立index,结束后就可以看到源码了,且不会提示无法找到头文件
OpenJDK-调试 (CLion)

2、openjdk 11及以下版本

openjdk11及以下的版本比较简单,直接导入就可以了,本文档中使用的是openjdk-11,操作路径如下:
File > New CMake Project from Sources
选择源码根目录,例如:/Users/saleson/c-projects/jdk-jdk-11-28
之后会出现如下界面,这些选项的内容最终会生成到CMakeLists.txt中
OpenJDK-调试 (CLion)
点击OK之后
OpenJDK-调试 (CLion)
通过这种方式导入,仍会有部分源文件上会提示找不到头文件。所以接下来本文档中均采用通过compile-commands.json方式导入的openjdk-16源码来进行调试。

调试

debug之前

需要配置构建目标,操作路径:
Preferences > Build, Exceution, Deployment > Custom Build Targets
OpenJDK-调试 (CLion)
最终打开Edit Tool编辑小面板,其中Tool Settings几个参数内容分别是:

Field Content
Program make
Arguments CONF=macosx-x86_64-normal-server-slowdebug
Working directory /Users/saleson/c-projects/jdk-jdk-16-ga

调试 java -version

在CLion右上方打开 Edit Configurations面板
OpenJDK-调试 (CLion)
新增Custom Build Application调试 java -version
OpenJDK-调试 (CLion)
Target: 选择前面创建好的Custom Build Target
Executable: 选择编译后的openjdk目录下的{openjdk}/build/macosx-x86_64-normal-server-slowdebug/jdk/bin/java 文件
Propram arguments: java 命令后面跟着的参数,例如:-version

在java.c文件的JavaMain()方法或者jni.cpp文件的JNI_CreateJavaVM_inner()方法上打上断点,点击右上角的debug,然后代码运行会停在断点处。
java.c文件的JavaMain()方法断点:
OpenJDK-调试 (CLion)
jni.cpp文件的JNI_CreateJavaVM_inner()方法断点:
OpenJDK-调试 (CLion)
执行结果:
OpenJDK-调试 (CLion)

忽略SIGEGV和SIGBUS信号

在调试过程会遇到下面这种情况
OpenJDK-调试 (CLion)
这是由于本案例中CLion采用的是LLDB 进行 debug 的,会处理SIGEGV和SIGBUS信号,避免这个问题的方法是在第一次断点处,在LLDB命令行面板中输入如下命令,就可以避免这个问题

pro hand -p true -s false SIGSEGV SIGBUS

OpenJDK-调试 (CLion)
此时debug的输出面板中就不会再出现 Signal: SIGSEGV (signal SIGSEGV) 这样的信息了
OpenJDK-调试 (CLion)

如果每次debug都要手动运行一次这样的命令也很麻烦,可以生成一个脚本文件。在用户目录下面创建.lldbinit文件

$ vim ~/.lldbinit

内容如下:

br set -n main -o true -G true -C "pro hand -p true -s false SIGSEGV SIGBUS"

这样就可以完美的解决问题了。

调试 java 类

写一个简单的测试代码:

package com.saleson.jdk;

import java.util.concurrent.locks.LockSupport;

/**
 * @author saleson
 * @date 2022-03-31 20:59
 */
public class Demo {

    public static void main(String[] args) throws Exception {
        LockSupport.park();
    }
}

在测试代码中调用LockSupport.park()方法,该方法会再调用Unsafe.park()这个native方法,到unsafe.cpp中定位到Unsafe_Park()方法,在此方法内设置断点
OpenJDK-调试 (CLion)

调试class文件

事先将Demo.java编译成class文件,新建Custom Build Application 进行调试
OpenJDK-调试 (CLion)

Field Content Describe
Program {openjdk}/build/macosx-x86_64-normal-server-slowdebug/jdk/bin/java 编译openjdk后的java命令
Arguments com.saleson.jdk.Demo 类路径
Working directory /Users/saleson/IdeaProjects/personal/target/classes com.saleson.jdk.Demo 的类目录

看一下断点调试情况
OpenJDK-调试 (CLion)

调试java文件

接下来选择使用java文件来进行调试,比之前要多一个步骤,在执行java com.saleson.jdk.Demo之前,先使用javac 命令编译java文件
OpenJDK-调试 (CLion)
Working directory改为跟class的输出目录。

添加compile java tool
OpenJDK-调试 (CLion)

Field Content Describe
Program {openjdk}/build/macosx-x86_64-normal-server-slowdebug/jdk/bin/javac 编译openjdk后的javac命令
Arguments -d /Users/saleson/Desktop/jdkdebug /Users/saleson/IdeaProjects/personal/src/main/java/com/saleson/jdk/Demo.java -d class输出目录, 后面跟着java文件路径

运行之后跟调试class是一样。

调试jar

仍以com.saleson.jdk.Demo为例,先使用maven编译jar包。在项目的 pom.xml中添加maven-plugin

build>
        plugins>
            plugin>
                artifactId>maven-assembly-pluginartifactId>
                configuration>
                    appendAssemblyId>falseappendAssemblyId>
                    descriptorRefs>
                        descriptorRef>jar-with-dependenciesdescriptorRef>
                    descriptorRefs>
                    archive>
                        manifest>
                            mainClass>com.saleson.jdk.DemomainClass>
                        manifest>
                    archive>
                configuration>
                executions>
                    execution>
                        id>make-assemblyid>
                        phase>packagephase>
                        goals>
                            goal>assemblygoal>
                        goals>
                    execution>
                executions>
            plugin>
        plugins>
    build>

在java工程根目录中执行mvn命令

$ mvn -DskipTests assembly:assembly
....
NOTE: If multiple descriptors or descriptor-formats are provided for this project, the value of this file will be non-deterministic!
[WARNING] Replacing pre-existing project main-artifact file: /Users/saleson/IdeaProjects/personal/target/personal-1.0-SNAPSHOT.jar
with assembly file: /Users/saleson/IdeaProjects/personal/target/personal-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 9.539 s
[INFO] Finished at: 2022-04-01T14:05:06+08:00
[INFO] Final Memory: 14M/47M
[INFO] ------------------------------------------------------------------------

新建运行jar包的Custom Build Application
OpenJDK-调试 (CLion)

Field Content Describe
Target 选择前面创建好的Custom Build Target
Executable {openjdk}/build/macosx-x86_64-normal-server-slowdebug/jdk/bin/java 选择编译后的openjdk目录下的java命令
Propram arguments -jar personal-1.0-SNAPSHOT.jar java 命令后面跟着的参数
Working directory /Users/saleson/IdeaProjects/personal/target jar所在的目录

运行后效果与前两种调试效果是一样的。

参考

https://segmentfault.com/a/1190000040305260
https://www.jianshu.com/p/ee7e9176632c
https://blog.csdn.net/qq_33543634/article/details/121187405
https://www.it1352.com/1570784.html
https://www.cnblogs.com/maxiaofang/p/6254392.html
https://blog.csdn.net/tiankong_12345/article/details/104088500
https://www.jianshu.com/p/0fc877be4c3d
https://blog.csdn.net/u012667477/article/details/119842942

    
原文链接:OpenJDK-调试 (CLion)
0 0 投票数
文章评分

本文为从大数据到人工智能博主「bajiebajie2333」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://lrting.top/backend/11766/

(0)
上一篇 2023-01-02 22:25
下一篇 2023-01-05 09:19

相关推荐

订阅评论
提醒
guest

0 评论
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论x