Determine whether .class file was compiled with debug info?

后端 未结 3 1974
情话喂你
情话喂你 2020-12-04 15:44

How can I determine for any Java .class file if that was compiled with debug info or not?

How can I tell exactly what -g{source|lines|vars} option was used?

相关标签:
3条回答
  • 2020-12-04 16:03

    You must check the Code structure in the class file and look for LineNumberTable and LocalVariableTable attributes.

    Tools like ASM or Apache Commons BCEL (Byte Code Engineering Library) will help: https://commons.apache.org/proper/commons-bcel/apidocs/index.html?org/apache/bcel/classfile/LineNumberTable.html

    0 讨论(0)
  • 2020-12-04 16:17

    Building on the two answers above (Aaron Digulla and Pete Kirkham), you can inspect the jarfile or the classfile directly with javap -v. I find this a little simpler than using a classpath. Single quotes are needed with the ! for the jarfile case.

    javap -v 'jar:file:///Absolute/Path/To/JarFile.jar!/package/name/using/slashes/ClassName.class' | grep "\(Compiled from\|LineNumberTable\|LocalVariableTable\)" | head
    

    or (don't need the absolute path for checking a classfile)

    javap -v Path/To/ClassName.class | grep "\(Compiled from\|LineNumberTable\|LocalVariableTable\)" | head
    

    If results are unclear or the format changes, pipe to less instead of grep and take a look.

    0 讨论(0)
  • 2020-12-04 16:23

    If you're on the command line, then javap -l will display LineNumberTable and LocalVariableTable if present:

    peregrino:$ javac -d bin -g:none src/Relation.java 
    peregrino:$ javap -classpath bin -l Relation 
    public class Relation extends java.lang.Object{
    public Relation();
    
    peregrino:$ javac -d bin -g:lines src/Relation.java 
    peregrino:$ javap -classpath bin -l Relation 
    public class Relation extends java.lang.Object{
    public Relation();
      LineNumberTable: 
       line 1: 0
       line 33: 4
    
    peregrino:$ javac -d bin -g:vars src/Relation.java 
    peregrino:$ javap -classpath bin -l Relation 
    public class Relation extends java.lang.Object{
    public Relation();
    
      LocalVariableTable: 
       Start  Length  Slot  Name   Signature
       0      5      0    this       LRelation;
    

    javap -c will display the source file if present at the start of the decompilation:

    peregrino:$ javac -d bin -g:none src/Relation.java 
    peregrino:$ javap -classpath bin -l -c Relation | head
    public class Relation extends java.lang.Object{
      ...
    
    peregrino:$ javac -d bin -g:source src/Relation.java 
    peregrino:$ javap -classpath bin -l -c Relation | head
    Compiled from "Relation.java"
    public class Relation extends java.lang.Object{
      ...
    

    Programmatically, I'd look at ASM rather than writing yet another bytecode reader.

    0 讨论(0)
提交回复
热议问题