【问题标题】:debug jdk source can't watch variable what it is调试 jdk 源无法查看变量它是什么
【发布时间】:2013-08-17 19:22:05
【问题描述】:

我正在调试 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;
    }

我想在进入if (isHighSurrogate(c1)) 之前查看c1 变量。 但是,当我调试手表 c1 变量时 它显示:

我确实尝试过添加rt.jar源,它确实可以进入JDK源的断点,例如:

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

【问题讨论】:

  • 其实一点也不难。查看我的更新答案
  • 为什么没有包含调试信息的 JDK 下载?

标签: java


【解决方案1】:

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

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

根据this post(请注意,我没有尝试过),您不需要编译所有源代码,只需编译您需要的源代码即可。将新编译的类放在 $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 &gt; 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 &gt;&gt; log.txt 2&gt;&amp;1 这将编译jdk_debug 文件夹中的所有文件,并在您的工作文件夹中生成一个log.txt 文件。检查日志内容。你应该得到一堆警告,但没有错误。
  8. 进入jdk_debug 文件夹并运行命令:jar cf0 rt_debug.jar *。这将生成带有调试信息的新运行时库。
  9. 将该新 jar 复制到文件夹 JDK_HOME\jre\lib\endorsed。如果endorsed 文件夹不存在,请创建它。

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

【讨论】:

  • 非常感谢,在item6中遇到问题:dir /B /S /X jdk7_src*.java > filelist.txt 什么是/B /S /X?
  • /B:没有其他文件信息。 /S:也读取子目录。 X:显示文件的短名称而不是长文件名。如果您运行dir /?,您可以看到此信息。
  • 效果很好!优秀的回应!您也可以对 src.zip 中未包含的部分 Java 代码库执行此操作,例如 SunJCE 加密提供程序。
  • 我刚刚在windows7编译jdk1.7.0-51的源代码,得到45个错误“error: cannot find symbol.”似乎需要包(sun.awt.*),但默认情况下在 jdk 源代码中找不到。
  • @subburoyal 也许您的 filelist.txt 没有正确生成。该消息说的是一个标志:D:\etr\java\java,我只能想象它在该文件中找到它。我会打开并检查文件以检查其中的源路径是否正确。您可能还想删除所有路径中的任何双引号。除此之外,我帮不上什么忙。
【解决方案2】:

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

【讨论】:

  • 我可以确认这是可行的,只是我使用 Intellij Idea 构建了 jar。只需将jar放入$jdk/jre/lib/endorsed即可正常调试!
  • 这在 Netbeans 中也适用于我。我做了:1. 创建一个新的空项目2. 将我想要的源文件复制到项目目录中的新文件夹3.将此目录添加到项目源文件 4. 清理并构建 5. 将 jar 从dist 目录复制到endorsed 目录。像魅力一样工作。
  • 这本身不是一个答案;它应该是对已接受答案的评论或编辑。
  • 我总是遇到 javac 错误(重新编译 jdk1.8 的 rt),但它在 Eclipse 中完美运行。谢谢!
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    您知道,认可的覆盖机制已被弃用,并将在未来的版本中删除 (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
    

    我复制到endorsed目录的rt.jar是原来的rt.jar,但是原来的类被我新生成的类替换了。

    【讨论】:

      【解决方案5】:

      如果有人需要使用 tomcat。您需要设置 VM 参数 Djava.endorsed.dirs 并将已编译的 jdk jar 放入其中。你可以做这个c-s的解决方案或者用eclipse导出(调试器使用的所有Java Compiler ClassFile Generation都必须是活动的)

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

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

      【讨论】:

        猜你喜欢
        • 2010-10-12
        • 2012-01-01
        • 2012-07-12
        • 2018-07-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-28
        相关资源
        最近更新 更多