41

我正在调试 JDK 源代码,例如:

 public static int codePointAt(CharSequence seq, int index) {
        char c1 = seq.charAt(index++);
        if (isHighSurrogate(c1)) {
            if (index < seq.length()) {
                char c2 = seq.charAt(index);
                if (isLowSurrogate(c2)) {
                    return toCodePoint(c1, c2);
                }
            }
        }
        return c1;
    }

我想c1在进入if (isHighSurrogate(c1)). 但是,当我调试监视c1变量时,它显示:

在此处输入图像描述

我确实尝试过添加rt.jar源,它确实可以进入JDK源的断点,例如: 在此处输入图像描述

但是为什么c1变量不能显示?

4

5 回答 5

75

一般来说,为了能够在单步执行 JDK 源代码时观察变量,您需要使用调试信息编译类文件,即使用javac -g.

所以你最好的选择是找到一个已经编译好的带有调试信息的版本(我找不到 JDK 7 的任何东西),或者你可以尝试自己编译源代码。

根据这篇文章(请注意,我没有尝试过),您不需要编译所有源代码,只需编译您需要的源代码。将新编译的类放在$jdk/jre/lib/ext/endorsed目录中,将使用新类而不是原始rt.jar.

我相信这应该让你开始。

更新:其实我刚刚尝试过这个过程,一点也不难。在 Windows、JDK 1.7.0_11 上测试。所有命令都从命令行调用:

  1. 创建您的工作文件夹。我选择了d:\根文件夹
  2. 在您的工作文件夹中创建源文件夹,即jdk7_src和输出文件夹jdk_debug
  3. 从您JDK_HOME的文件夹中获取src.zip文件并将其解压缩到里面jdk7_src
  4. 选择您将编译的内容并删除其余部分。对于所有这些,您可能需要额外的步骤。我选择了文件夹:
    • java
    • javax
    • org
  5. 从您JDK_HOME\jre\lib获取文件rt.jar并放入工作文件夹(这只是为了方便,不要在命令行中指定太大的文件名)。
  6. 执行命令:dir /B /S /X jdk7_src\*.java > filelist.txt创建一个文件filelist.txt,该文件以将要编译的所有 java 文件的列表命名。这将作为输入javac
  7. javac使用命令执行:
    javac -J-Xms16m -J-Xmx1024m -sourcepath d:\jdk7_src -cp d:\rt.jar -d d:\jdk_debug -g @filelist.txt >> log.txt 2>&1这将编译文件夹中的所有文件,并在您的工作文件夹中jdk_debug生成一个文件。log.txt检查日志内容。你应该得到一堆警告,但没有错误。
  8. 进入jdk_debug文件夹并运行命令:jar cf0 rt_debug.jar *. 这将生成带有调试信息的新运行时库。
  9. 将该新 jar 复制到文件夹JDK_HOME\jre\lib\endorsed中。如果该endorsed文件夹不存在,请创建它。

在 Eclipse 中调试您的程序。注意变量是如何正常命名的(不再是 arg0、arg1 等)。调试愉快:)

JDK调试

于 2013-08-15T15:16:07.743 回答
14

cs 的 jre\lib\endorsed 解决方案很棒。使用 Eclipse 更容易构建:创建一个 Java 项目,将 javax*、java* 放入 src 并让 Eclipse 编译。然后导出罐子。

于 2013-09-26T14:01:23.657 回答
1

这篇文章http://www.thejavageek.com/2016/04/03/debug-jdk-source-code/描述了相同的内容,但以简单而好的方式。您只使用 eclipse 来做事(编译、制作 jar)。

于 2016-12-01T12:42:00.370 回答
0

如您所知,认可的覆盖机制已被弃用,并将在未来的版本中删除( http://docs.oracle.com/javase/8/docs/technotes/guides/standards/ )。

使用它来获取带有调试信息pom.xml的 JDK源:1.8.0_111

<project>

  <modelVersion>4.0.0</modelVersion>
  <name>JDK sources with debug information</name>

  <groupId>ex.jdk.debug</groupId>
  <artifactId>jdk-debug-sources</artifactId>
  <version>1.8.0_111</version>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>com.oracle</groupId>
      <artifactId>jdk-rt</artifactId>
      <version>1.8.0_111</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.6.0</version>
        <configuration>
          <debug>true</debug>
          <debuglevel>lines,vars,source</debuglevel>
          <source>1.8</source>
          <target>1.8</target>
          <excludes>
            <exclude>com/sun/java/swing/**</exclude>
            <exclude>com/sun/source/util/**</exclude>
          </excludes>
        </configuration>
      </plugin>

    </plugins>
  </build>

 </project>

您必须手动安装原始rt.jar版本才能运行mvn clean install

mvn install:install-file -Dfile=rt.jar -DgroupId=com.oracle -DartifactId=jdk-rt -Dversion=1.8.0_111 -Dpackaging=jar

rt.jar我复制到endorsed目录的是原始的,rt.jar但原始类被我新生成的类所取代。

于 2017-01-03T08:01:04.307 回答
0

万一有人需要这个tomcat。您需要设置 VM 参数 Djava.endorsed.dirs 并将已编译的 jdk jar 放入其中。您可以执行此 cs 的解决方案或使用 eclipse 导出(调试器使用的所有 Java Compiler ClassFile Generation 必须处于活动状态)

转到运行配置 > 参数 > VM 参数

Djava.endorsed.dirs="/your/folder/apache-tomcat-xxx/endorsed"

于 2018-03-06T12:18:25.897 回答