记录已执行 Java 代码的行号

2022-09-04 23:05:45

我正在编写PHP Web应用程序的一部分(将在高中错误查找竞赛中使用),用户必须在给定的Java程序中查找错误。作为其中的一部分,当 Java 程序执行时,我们希望突出显示执行代码的 Java 程序源的行。为此,我们只需要已执行的源代码的行号,即代码路径(或者它被称为代码覆盖率?)。我们将使用行号突出显示源文件中的行。

我们将使用PHP的shell-exec()来执行Java程序和工具来获取代码路径(无论它将是什么)。获取代码路径行号的最简单方法是什么?

谢谢!

这是一张图片,描述了我们想要什么

enter image description here


答案 1

PHP会插入代码,这意味着每次运行程序时,它都会在源代码上运行。这样做的好处是,在读取代码时会爆炸(这使得行号打印输出变得微不足道);但是,在其他方面,它通常很昂贵,因为您无法进行深度优化(或进行任何运行时前错误检查)。

Java将其代码编译为一种名为“字节码”的JVM汇编语言。这意味着正在运行的内容通常无法访问(甚至不使用)源代码。也就是说,有技术。编译后的Java类能够添加“额外数据”,其中一个“额外数据元素”是行号表,它是一个索引,允许运行程序集的人在编译器记录时“查找”行号。

这通常可以正常工作,并考虑到:编译器通常不会标记每个指令,源代码可能不可用,优化可能会使某些内部代码块无法以方便指向输入代码文本的方式运行。

代码覆盖率工具如何“修复”这一点,即它们通常会在代码中(在程序集级别)插入大量命令,这些命令有效地充当记录语句的格式,该格式允许工具确定实际遵循代码的路径。然后,它尽可能通过行号表映射回去,然后用于突出显示原始源文件中的行。

如果你想要一些分辨率更精细的东西(可以处理一条线的哪一部分被执行),那么你需要更深入地挖掘。最终,您甚至可以考虑编写自己的编译器(或编译器扩展),它将存储您自己的自定义行号表,以克服当前解决方案的缺点。

像抛出异常(正如Shiven所提到的)和解析行号这样的技巧确实有效;但是,它们会污染您的代码,对实际上不是异常的项目进行奇怪的异常处理,只是为了“获取行号”。由于代码混乱和异常的运行时性能通常较差,我倾向于避免这样的解决方案(但它们确实有效)。

无论如何,希望这能给你一个观点,为什么它并不总是以与PHP完全相同的方式工作。


答案 2

看看科贝图拉。它计算覆盖率和类似的东西,如果它还没有这样做,那么将行号收集添加到它应该相对容易。有一个非常黑客的尝试来做到这一点,但这太慢了,你可能无法在生产 https://bitbucket.org/jowu/myriapod/wiki/Home


推荐