自定义 JVM 语言:创建可行的堆栈跟踪?

Posted

技术标签:

【中文标题】自定义 JVM 语言:创建可行的堆栈跟踪?【英文标题】:Custom JVM Language: Creating workable stack traces? 【发布时间】:2017-07-04 01:33:25 【问题描述】:

JVM 上的堆栈跟踪如何工作?

是否可以将类文件转换为具有与父语言相关的堆栈跟踪,而不是伪 java 文件?

具体来说,这个 Mixin 库 https://github.com/SpongePowered/Mixin 是否可以修改,这样当它覆盖/注入代码到方法中时,如果发生错误,它会指向源中正确的 mixin 伪类?

【问题讨论】:

【参考方案1】:

根本不需要Java源代码文件。

只有两个相关的属性。

    SourceFile 类属性指定源代码文件的名称,它不必是.java 文件。

    LineNumberTable 属性应用于Code 属性,说明字节码指令如何映射到源代码行。

堆栈跟踪仅报告上述两个属性所报告的类和方法名称以及源文件名和行号。它背后没有额外的语义。

这些属性已经足以进行单步调试,因为调试器只需要加载指定的文件(假设它是基于文本的)并突出显示特定的行。我已经以这种方式单步执行了一个 XSLT 文件,该文件已被 XSLT 处理器动态编译为字节码。如果要使局部变量可检查,还必须在代码中添加LocalVariableTable 属性。

我还使用它们来生成代码,其元信息指向触发代码生成的原始代码。甚至在编译普通 Java 源代码时也会发生这种情况,因为为 lambda 表达式生成的合成方法具有指向定义它的源代码级方法中的 lambda 表达式的行号表。

【讨论】:

一个类文件可以由多个源文件组成是否重要?在 Mixin 库中,在类加载时通过转换器在类上添加和替换方法。 好吧,SourceFile属性只有一个,所以你只能指向一个源文件。你通常通过使用委托来解决这个问题,只有非常小的注入代码,它会调用其他类文件中的代码,这些文件也可以在调试信息中指向不同的源文件。 堆栈跟踪不尊重 jcp.org/en/jsr/detail?id=45 有点烦人 老实说,我不知道 Oracle 的 JVM 在生成堆栈跟踪时是否会解释 SourceDebugExtension 属性。 JVM 规范没有说明它的任何内容,因此在支持任意 JVM 时显然没有什么可以依赖的。而且我从未遇到过具有多个源和SourceDebugExtension 属性的类文件。

以上是关于自定义 JVM 语言:创建可行的堆栈跟踪?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 ETW 编写自定义堆栈跟踪

Logback - 如何编写自定义异常转换器以将堆栈跟踪折叠成一行

如何为自定义JVM语言实现静态代码分析工具的类型信息?

自定义异常类型

自定义 UIControl,动作调用两次

自定义异常 python + Sentry stacktrace