42

I'm debugging the JDK source like:

 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;
    }

and I want to see c1 variable before I step into if (isHighSurrogate(c1)). However, when I debug watch c1 variable it display :

enter image description here

I really have tried added rt.jar source, and it really can step into breakpoint of JDK source, like: enter image description here

but why c1 variable can't display?

王奕然
  • 3,891
  • 6
  • 41
  • 62

5 Answers5

78

Generally speaking, to be able to watch the variables while stepping through JDK source code, you need the class files to be compiled with debug information i.e. compile using javac -g.

So your best bet is to either find an already compiled version with debug information (I couldn't find anything for JDK 7) or you can try compiling the source for yourself.

According to this post (please note that I haven't tried it) you don't need to compile all sources, only the ones you need. Putting your newly compiled classes in the $jdk/jre/lib/ext/endorsed directory, the new classes would be used instead the ones in the original rt.jar.

I believe that should get you started.

Update: Actually I have just tried this process and it is not hard at all. Tested on Windows, JDK 1.7.0_11. All the commands are invoked from command line:

  1. Create your working folder. I chose d:\ root folder
  2. Inside your working folder create the source folder i.e. jdk7_src and output folder jdk_debug
  3. From your JDK_HOME folder get the src.zip file and unzip it inside jdk7_src
  4. Select what you will compile and delete the rest. For all of them you might need additional steps. I have chosen the folders:
    • java
    • javax
    • org
  5. From your JDK_HOME\jre\lib get the file rt.jar and put in the work folder (this is only for convenience to not specify too large file names in the command line).
  6. Execute the command: dir /B /S /X jdk7_src\*.java > filelist.txt to create a file named filelist.txt with the list of all java files that will be compiled. This will be given as input to javac
  7. Execute javac using the command:
    javac -J-Xms16m -J-Xmx1024m -sourcepath d:\jdk7_src -cp d:\rt.jar -d d:\jdk_debug -g @filelist.txt >> log.txt 2>&1 This will compile all the files in the jdk_debug folder and will generate a log.txt file in your working folder. Check the log contents. You should get a bunch of warnings but no error.
  8. Go inside the jdk_debug folder and run the command: jar cf0 rt_debug.jar *. This will generate your new runtime library with degug information.
  9. Copy that new jar to the folder JDK_HOME\jre\lib\endorsed. If the endorsed folder does not exist, create it.

Debug your program in Eclipse. Note how the variables are named normally (no more arg0, arg1 etc). Happy debugging :)

JDK debug

c.s.
  • 4,786
  • 18
  • 32
  • thanks very much, and i encounter a problem in item6:dir /B /S /X jdk7_src\*.java > filelist.txt what is /B /S /X? – 王奕然 Aug 16 '13 at 07:09
  • 1
    `/B`: no additional file info. `/S`: read subdirectories too. `X`: shows the short names of the files instead of long file names. You can see this information if you run `dir /?`. – c.s. Aug 16 '13 at 07:15
  • Worked great! Excellent response! You can also do this for parts of the Java codebase that aren't included in src.zip, like the SunJCE crypto provider. – voetsjoeba May 27 '14 at 18:56
  • This is great info, but for convenience see @weberjn's answer. – David Groomes Jul 28 '14 at 14:49
  • 2
    I just compiled the source code of jdk1.7.0-51 in windows7, got 45 errors "error: cannot find symbol." It seems the package (sun.awt.*) is needed, however does not locate by default in the jdk source code. – rekinyz Aug 01 '14 at 13:47
  • Brilliant! I though't compiling would take ages. It took 3mins on my pc. Now I can see the variables. Thanks a lot! – Aykut Kllic Jun 15 '16 at 09:18
  • @rekinyz same with jdk1.8.0_91 on ubuntu. any solution in sight? – derwiwie Jun 20 '16 at 07:38
  • while doing step7 I am getting this error in log.txt `javac:invalidflag: usage:javac ` how to fix this? @c.s. – subbu royal Dec 08 '16 at 03:10
  • @subburoyal What is the command you are using? From the message it seems that either you enter an invalid option or the file with the list of the sources is not recognized (perhaps mispelled?) – c.s. Dec 08 '16 at 06:37
  • I am using this command `javac -J-Xms16m -J-Xmx1024m -sourcepath "D:\etr\java\debug\jdk_source" -cp "D:\etr\java\debug\rt.jar" -d "D:\etr\java\debug\jdk_debug" -g @filelist.txt >> log.txt 2>&1` and I am getting this `javac: invalid flag: D:\etr\java\java Usage: javac use -help for a list of possible options` all files are there in the mentioned location. can you plz help me what is the mistake I am doing? @c.s. – subbu royal Dec 08 '16 at 07:40
  • 1
    @subburoyal perhaps your filelist.txt was not generated correctly. The message says about a flag: `D:\etr\java\java` which I can only imagine that it finds it inside that file. I would open and examine the file to check if the source paths in there are correct. You might also want to remove any double quotes in all paths. Other than that I can't help much. – c.s. Dec 08 '16 at 10:57
  • @c.s. Thank you very much, I changed location of `filelist.txt` after creating and I tried step 7, as per ur suggestion I saw the location by opening `filelist.txt` and I realized that the path is different and compiling in different location. Now I fixed the issue by changing the location to this path `D:\etr\java\debug` once again thank you very much. Now I am able to see the local variable values while debugging. – subbu royal Dec 08 '16 at 11:50
  • I get an emtpy output directory for jdk1.8.0_111 :/ – aliopi Jan 03 '17 at 06:37
  • I tried to same steps for JDK8_101, and I got also empty jdk_debug. I check the filelist.txt and all paths are good. Any idea why to fix it? – Nehad Nov 28 '21 at 18:45
  • I figured out what was the problem. I have two JDK installed 11, and 8, and I was using JDK11 to build JDK8 source files. Once the correct version is used, it worked. – Nehad Nov 30 '21 at 11:31
14

c-s's jre\lib\endorsed solution is great. Easier to build is with Eclipse: create a Java project, put javax*, java* into src and let Eclipse compile. Then export the jar.

weberjn
  • 1,840
  • 20
  • 24
  • 1
    I can confirm this works, except that I built the jar using Intellij Idea. Simply put the jar in `$jdk/jre/lib/endorsed` and voila you can debug normally! – David Groomes Jul 28 '14 at 14:48
  • 1
    This worked for me in Netbeans as well. I did: *1.* create a new empty project *2.* copy the source files I wanted in to a new folder inside the project directory *3.* add this directory to project source files *4.* clean and build *5.* copy the jar from the `dist` directory to the `endorsed` directory. Worked like a charm. – Radiodef Jun 12 '15 at 16:25
  • This is not an answer by itself; it should be a comment or edit to the accepted answer. – E-Riz Mar 08 '16 at 15:16
  • I was always having errors with javac (recompiling rt of jdk1.8), but it worked flawlessly in Eclipse. Thanks! – qwertzguy Jul 07 '16 at 23:29
1

This article http://www.thejavageek.com/2016/04/03/debug-jdk-source-code/ describe the same but in simple and nice way. You do stuff(compile,make jar) by using eclipse only.

Andrew
  • 479
  • 5
  • 15
0

Just so you know, the endorsed override mechanism is deprecated and will be removed in a future release (http://docs.oracle.com/javase/8/docs/technotes/guides/standards/).

Use this pom.xml to get JDK 1.8.0_111 sources with debug information:

<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>

You'll have to do a manual install of the original rt.jar to be able to run mvn clean install

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

The rt.jar I copied to the endorsed directory is the original rt.jar but with the original classes replaced by my newly generated classes.

aliopi
  • 3,682
  • 2
  • 29
  • 24
0

In case anybody needs this with tomcat. You need to set up the VM argument Djava.endorsed.dirs and put your compiled jdk jar in it. You can do this c-s's solution or exported with eclipse(all the Java Compiler ClassFile Generation used by de debugger must be active)

Go to Run Configurations > Arguments > VM arguments

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

PbxMan
  • 7,525
  • 1
  • 36
  • 40