I met an issue when I wanted to debug jdk source code that eclipse can’t resolve the value of the arguments in functions and it’s not able to see the arguments’ name, however the arguments values are readable in variables view:
Why is this?
In fact, when compile the java source code in eclipse of rt.jar, oracle chose to remove the debug information so that we can’t debug directly for local variables even if we can see the source code. That’s too bad, and to explain this, we can test locally.
I have a LocalVariableTableTest class, and compile it using javac, then move the manually compiled class file into my target classes folder:
After doing this, I set a break-point in line 10 and start to debug, this time we can find out we can’t see the argument number either:
And of course I can’t resolve the value of number, because JVM totally has no idea what does this mean.
In JVM specification, we know that code structures contain an attribute naming “LocalVariableTable” which used to describe the local variables. This attribute is important for debugging to bind the variable in source code to local variables in stacks. When compile source code this is optional and we can choose whether to generate this information, and if not, all the names of local variables will be lost, IDE may take placeholders for displaying.
Now, I compile my class with option -g to produce debug information including “LocalVariableTable” and then use ”javap -verbose LocalVariableTableTest” to see the bytecodes of this class:
Now I can see the LocalVariableTable attributes are generated, next, debug my class again:
This time, the variable is displayed correctly.
So the reason is known for the issues I met when debug jdk source code. how to fix it? The core concept is to compile classes with debug information.
Refer to some of the online solutions, you may fix it with below steps:
- Unzip the source.zip in your jdk to a folder assumes naming it Folder_A, and choose the packages you want to keep, generally java,javax,org is enough.
- Execute command under above folder: dir /B /S /X jdk_src\*.Java > filelist.txt to produce a text file naming filelist contains all the class names we will compile.
- Copy rt.jar under path: your_jdk_home/jre/lib to Folder_A.
- Create a folder for example d:\debug_rt\classes, then execute command:If this command executed successfully, you should able to see class files compiled under d:\debug_rt\classes.
- If error happens, you can open Folder_A’s path/log.txt to see which class has error then delete it and do the process again till you succeed
- javac -J-Xms16m -J-Xmx1024m -sourcepath Folder_A’s path\src -cp Folder_A’s path \rt.jar -d d:\debug_rt\classes -g @filelist.txt:
- After all the class files are ready, packaging them as rt_debug.jar, and now this can be used to debug! In eclipse, we can directly add this external jar to jre libarary and then attach source code, then everything is done.