0

プログラムで JDB を操作しようとしています。正常なデバッガとは異なり、JDB はソース ファイル名の代わりにクラス名を使用してソース コードを参照します。バイトコードを単一のファイルではなく複数の .class ファイルに格納することに関連していると思います(-gフラグを使用してコンパイルすると、ソースファイルへの参照が生成されると予想されますが、物事を簡単にするのはJavaの方法ではありません... )

JDB がクラスを参照する場合、通常は文字列操作をいくつか行い、ソース ファイル名を調べて、どのソース ファイルが関連するクラスを宣言しているかを判断します。ブレークポイントのクラス名を指定する必要がある場合は、ファイルを読み取ってパッケージ名を取得し、そのファイル名をクラス名として使用して、その方法で完全なクラス名を生成できます。これらの2つのケースは、私がそれらを機能させました。

問題は内部クラスと匿名クラスから始まります。それらは独自のクラス ファイルに存在し、それらの名前はそれらを含むクラスのマングル バージョンです。そこにブレークポイントを設定するには、マングルされた名前が必要です。

例-これはMain.java(+行番号)です:

1: public class Main{
2:    public static void main(String[] args){
3:        new Object(){
4:            @Override public String toString(){
5:                System.out.println("hi");
6:                return "";
7:            }
8:        }.toString();
9:    }
10:}

を使用してコンパイルしjavac -g Main.java、 を取得Main.classMain$1.classました。私は走っていjdbます:

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

Breakpoint hit: "thread=main", Main.main(), line=3 bci=0
3               new Object(){

(その部分をロードする必要がありました。Main.classそうしないと、すべてのブレークポイント設定の試行に対して、「クラスがロードされた後に設定されます。 」と表示されます。)

8 行目にブレークポイントを設定すると、正しく動作します。

main[1] stop at Main:8
Set breakpoint Main:8

匿名クラスの一部である 5 行目にブレークポイントを設定すると、エラーが発生します。

main[1] stop at Main:5
Unable to set breakpoint Main:5 : No code at line 5 in Main

行 5 には明らかにコードが含まれています。問題は、コードが にコンパイルされていないことです。コードは にコンパイルされMain.classMain$1.classいるため、代わりに次のように記述する必要があります。

main[1] stop at Main$1:5
Deferring breakpoint Main$1:5.
It will be set after the class is loaded.

さて、Java がバイトコードを .class ファイルに分割する方法は決定論的であり、この単純な例では、人間の目で調べると、何がどこにあるのかを簡単に把握できますが、マングルされたクラス名をプログラムで把握する方法が必要です( VimScript を使用) 実際のソース ファイルの場合。ソース ファイルを構文的に分析し、どれが複雑すぎるのかを突き止めようとしています。もっと簡単な方法があるはずです。

おそらく、.class ファイルからその情報を抽出するか、それについて JDB に質問するか、JDB に、正常な言語の正常なデバッガーのようにソース ファイル名を使用させることさえできます...

4

1 に答える 1