【问题标题】:Determine whether .class file was compiled with debug info?确定 .class 文件是否使用调试信息编译?
【发布时间】:2009-10-02 08:00:24
【问题描述】:

如何确定任何 Java .class 文件是否使用调试信息编译?

我怎样才能确切地知道使用了什么 -g{source|lines|vars} 选项?

【问题讨论】:

    标签: java class debugging


    【解决方案1】:

    如果您在命令行上,则 javap -l 将显示 LineNumberTable 和 LocalVariableTable(如果存在):

    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 将显示源文件(如果在反编译开始时存在):

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

    以编程方式,我会查看ASM,而不是编写另一个字节码阅读器。

    【讨论】:

      【解决方案2】:

      您必须检查类文件中的Code structure 并查找LineNumberTableLocalVariableTable 属性。

      ASM 或 Apache Commons BCEL(字节码工程库)等工具会有所帮助:https://commons.apache.org/proper/commons-bcel/apidocs/index.html?org/apache/bcel/classfile/LineNumberTable.html

      【讨论】:

      • 这些链接现在都坏了。
      • @GreenGiant 已修复。
      【解决方案3】:

      基于上述两个答案(Aaron Digulla 和 Pete Kirkham),您可以直接使用 javap -v 检查 jarfile 或 classfile。我发现这比使用类路径要简单一些。对于 jarfile 情况,! 需要单引号。

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

      或者(不需要绝对路径来检查类文件)

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

      如果结果不清楚或格式更改,请通过管道发送到 less 而不是 grep 并查看。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-03-14
        • 2019-11-08
        • 1970-01-01
        • 1970-01-01
        • 2018-09-16
        • 2017-12-24
        • 1970-01-01
        相关资源
        最近更新 更多