13

ユーザーが特定の Java プログラムのバグを見つけなければならない PHP Web アプリケーション (高校のバグ発見コンテストで使用される) の一部を作成しています。その一環として、Java プログラムの実行時に、コードが実行された Java プログラムのソースの行を強調表示します。これを行うために必要なのは、実行されたソースの行番号、つまりコード パス (またはコード カバレッジと呼ばれますか?) だけです。行番号を使用して、ソース ファイル内の行を強調表示します。

PHP の shell-exec() を使用して Java プログラムを実行し、ツールを使用してコード パスを取得します (それが何であれ)。コード パスの行番号を取得する最も簡単な方法は何ですか?

どうもありがとうございました!

これが私たちが望むものを説明する写真です

ここに画像の説明を入力

4

5 に答える 5

4

PHPはコードを解釈します。つまり、プログラムを実行するたびにソース上で実行されます。これには、コードが読み取られるときに爆発するという利点があります(これにより、行番号の印刷が簡単になります)。ただし、深く最適化できない(または実行前のエラーチェックを実行できない)ため、他の方法ではコストがかかることがよくあります。

Javaは、そのコードを「バイトコード」と呼ばれるJVMアセンブリ言語にコンパイルします。 これは、実行中のものが通常、ソースコードにアクセスできない(または使用しない)ことを意味します。とはいえ、テクニックがあります。コンパイルされたJavaクラスには「追加データ」を追加する機能があり、それらの「追加データ要素」の1つは行番号テーブルです。これは、アセンブリを実行している誰かが、コンパイラが記録した行番号を「検索」できるようにするインデックスです。。

これは通常、次の点を考慮して問題なく機能します。コンパイラはすべての命令をマークアップしないことが多く、ソースコードが利用できない場合があり、最適化により、入力コードテキストを指すのを容易にする方法でコードの特定の内部チャンクが機能しなくなる場合があります。

コードカバレッジツールがこれを「修正」する方法は、通常、コード内のどのパスが実際にたどられたかをツールが判断できる形式へのログステートメントとして効果的に機能する多数のコマンドを(アセンブリレベルで)コードに挿入することです。 。次に、これは可能な限り行番号テーブルにマッピングされ、元のソースファイル内の行を強調表示するために使用されます。

より細かい解像度の何か(行のどの部分が実行されたかを処理できるもの)が必要な場合は、さらに深く掘り下げる必要があります。最終的には、現在のソリューションの欠点を克服する独自のカスタム行番号テーブルを格納する独自のコンパイラ(またはコンパイラ拡張)を作成することを検討することもできます。

(Shivenが述べたように)例外をスローしたり、行番号を解析したりするようなトリックは機能します。ただし、 「行番号を取得する」ためだけに、実際には例外ではないアイテムの奇妙な例外処理でコードを汚染します。コードが乱雑で、例外の実行時パフォーマンスが一般的に低いため、私はそのような解決策を避ける傾向があります(ただし、それらは機能します)。

とにかく、うまくいけば、これにより、PHPとまったく同じように機能するとは限らない理由がわかります。

于 2012-06-01T16:20:47.810 に答える
1

コベルチュラを見てください。カバレッジなどを計算します。まだ実行していない場合は、行番号の収集を比較的簡単に追加できます。それを行うための非常にハックな試みがありますが、それは非常に遅いため、本番環境で使用できない場合がありますhttps://bitbucket.org/jowu/myriapod/wiki/Home

于 2012-06-01T16:27:43.330 に答える
0

このリンクJVMDIを参照してみてください

プログラムカウンターの値にアクセスしてから、それを lineNumberTable にマップできます。または、JVMDI には、実行中のコードの行番号にアクセスできるメソッドがあると思います。後者についてはわかりません。上記のリンクを参照して、お役に立てば幸いです。

于 2012-09-03T10:32:47.313 に答える
0

私はこのようなことをしたことも見たこともありませんが、興味深い問題のように思えます。私の考えでは、コマンドだけでなく、Java デバッガー (jdb)javaを使用してコードを実行することです。

(jdb のコマンドを使用して) 行ごとにコードをステップstep実行でき、行が実行されるたびにその行番号が吐き出されます。これには PHP 側の助けが少し必要ですが (行番号を解析し、次のステップのコマンドを実行する必要があります)、行番号はそこにあります。以下は、非常に基本的な Java プログラムからのサンプル出力です。

Java (TestClass.java)

public class TestClass {
   public static void main(String[] args) {
      System.out.println("foo");
      System.out.println("bar");
   }
}

jdb (実行後のjdb TestClass javac TestClass.java)

Initializing jdb ...
> stop at TestClass:3
Deferring breakpoint TestClass:3.
It will be set after the class is loaded.
> run
run TestClass
Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
> 
VM Started: Set deferred breakpoint TestClass:3

Breakpoint hit: "thread=main", TestClass.main(), line=3 bci=0
3          System.out.println("foo");

main[1] step
> foo

Step completed: "thread=main", TestClass.main(), line=4 bci=8
4          System.out.println("bar");

main[1] step
> bar

Step completed: "thread=main", TestClass.main(), line=5 bci=16
5        }

main[1] step
> 
The application exited
于 2012-06-01T16:28:42.397 に答える
0

-g オプションを指定してプログラムをコンパイルし、printStackTrace() を実行し、トレース出力をキャプチャして、そこから行番号を抽出すると、行番号を取得できます。

于 2012-06-01T16:11:52.917 に答える