【发布时间】:2017-07-04 01:33:25
【问题描述】:
JVM 上的堆栈跟踪如何工作?
是否可以将类文件转换为具有与父语言相关的堆栈跟踪,而不是伪 java 文件?
具体来说,这个 Mixin 库 https://github.com/SpongePowered/Mixin 是否可以修改,这样当它覆盖/注入代码到方法中时,如果发生错误,它会指向源中正确的 mixin 伪类?
【问题讨论】:
标签: jvm
JVM 上的堆栈跟踪如何工作?
是否可以将类文件转换为具有与父语言相关的堆栈跟踪,而不是伪 java 文件?
具体来说,这个 Mixin 库 https://github.com/SpongePowered/Mixin 是否可以修改,这样当它覆盖/注入代码到方法中时,如果发生错误,它会指向源中正确的 mixin 伪类?
【问题讨论】:
标签: jvm
根本不需要Java源代码文件。
只有两个相关的属性。
SourceFile 类属性指定源代码文件的名称,它不必是.java 文件。
LineNumberTable 属性应用于Code 属性,说明字节码指令如何映射到源代码行。
堆栈跟踪仅报告上述两个属性所报告的类和方法名称以及源文件名和行号。它背后没有额外的语义。
这些属性已经足以进行单步调试,因为调试器只需要加载指定的文件(假设它是基于文本的)并突出显示特定的行。我已经以这种方式单步执行了一个 XSLT 文件,该文件已被 XSLT 处理器动态编译为字节码。如果要使局部变量可检查,还必须在代码中添加LocalVariableTable 属性。
我还使用它们来生成代码,其元信息指向触发代码生成的原始代码。甚至在编译普通 Java 源代码时也会发生这种情况,因为为 lambda 表达式生成的合成方法具有指向定义它的源代码级方法中的 lambda 表达式的行号表。
【讨论】:
SourceFile属性只有一个,所以你只能指向一个源文件。你通常通过使用委托来解决这个问题,只有非常小的注入代码,它会调用其他类文件中的代码,这些文件也可以在调试信息中指向不同的源文件。
SourceDebugExtension 属性。 JVM 规范没有说明它的任何内容,因此在支持任意 JVM 时显然没有什么可以依赖的。而且我从未遇到过具有多个源和SourceDebugExtension 属性的类文件。