IntelliJのデバッグトリック

IntelliJデバッグのコツ

1. 概要

このチュートリアルでは、いくつかのadvanced IntelliJ debugging facilitiesを調べます。

デバッグの基本(デバッグの開始方法、Step IntoStep Overアクションなど)はすでにわかっていることを前提としています。 そうでない場合は、その詳細についてthis articleを参照してください。

2. スマートステップイントゥ

doJob(getArg1(), getArg2())のように、1行のソースコードで複数のメソッドが呼び出される場合があります。 Step Intoアクション(F7)を呼び出すと、デバッガーは、評価のためにJVMで使用される順序(getArg1getArg2doJob)でメソッドに入ります。

ただし、we might want to skip all intermediate invocations and proceed to the target method directlySmart Step Intoアクションはそれを可能にします。

bound to the Shift + F7 by defaultであり、呼び出されると次のようになります。

image

これで、ターゲットメソッドを選択して続行できます。 また、IntelliJは常に最も外側のメソッドをリストの一番上に配置することに注意してください。 つまり、Shift + F7 |を押すと、すぐに移動できます。 Enter

3. ドロップフレーム

関心のある処理がすでに行われていることに気付く場合があります(例: 現在のメソッド引数の計算)。 この場合、it’s possible to drop the current JVM stack frame(s) in order to re-process them.

以下の状況を検討してください。

image

getArg1処理のデバッグに関心があるとすると、現在のフレームを削除します(doJobメソッド)。

image

we’re in the previous method

image

ただし、呼び出し引数はこの時点ですでに計算されているため、we need to drop the current frame as well

image

これで、Step Intoを呼び出して処理を再実行できます。

4. フィールドブレークポイント

非プライベートフィールドは、セッターを介さずに直接、他のクラスによって変更される場合があります(これは、ソースコードを制御しないサードパーティライブラリの場合です)。

このような状況では、変更がいつ行われるかを理解するのが難しい場合があります。 IntelliJでは、フィールドレベルのブレークポイントを作成して追跡できます。

これらは通常どおりに設定されます。フィールド行の左側のエディターのガターを左クリックします。 その後、open breakpoint properties (right-click on the breakpoint mark) and configure if we’re interested in the field’s reads, writes, or bothを実行できます。

image

5. ブレークポイントのロギング

アプリケーションに競合状態があることはわかっていても、正確にどこにあるのかわからない場合があります。 特に新しいコードを使用する場合は、特定するのが難しい場合があります。

プログラムのソースにデバッグステートメントを追加できます。 ただし、サードパーティのライブラリにはそのような機能はありません。

IDEはここで役立ちます–it allows setting breakpoints that don’t block execution once hit, but produce logging statements instead

次の例を見てください。

public static void main(String[] args) {
    ThreadLocalRandom random = ThreadLocalRandom.current();
    int count = 0;
    for (int i = 0; i < 5; i++) {
        if (isInterested(random.nextInt(10))) {
            count++;
        }
    }
    System.out.printf("Found %d interested values%n", count);
}

private static boolean isInterested(int i) {
    return i % 2 == 0;
}

実際のisInterested呼び出しのパラメータをログに記録することに関心があるとします。

ターゲットメソッドに非ブロッキングブレークポイントを作成しましょう(Shift +左側のエディターガターを左クリックします)。 その後、そのプロパティ(ブレークポイントを右クリック)とdefine the target expression to logを開きます。

image

アプリケーションを実行すると(デバッグモードを使用する必要があることに注意してください)、次の出力が表示されます。

isInterested(1)
isInterested(4)
isInterested(3)
isInterested(1)
isInterested(6)
Found 2 interested values

6. 条件付きブレークポイント

特定のメソッドが複数のスレッドから同時に呼び出され、特定の引数についてのみ処理をデバッグする必要がある場合があります。

IntelliJはcreating breakpoints that pause the execution only if a user-defined condition is satisfiedを許可します。

上記のソースコードを使用する例を次に示します。

imageimage

これで、デバッガーは、指定された引数が3より大きい場合にのみブレークポイントで停止します。

7. オブジェクトマーク

これは最も強力で、あまり知られていないIntelliJ機能です。 本質的には非常に単純です–we can attach custom labels to JVM objects

それらをデモンストレーションするために使用するアプリケーションを見てみましょう。

public class Test {

    public static void main(String[] args) {
        Collection tasks = Arrays.asList(new Task(), new Task());
        tasks.forEach(task -> new Thread(task).start());
    }

    private static void mayBeAdd(Collection holder) {
        int i = ThreadLocalRandom.current().nextInt(10);
        if (i % 3 == 0) {
            holder.add(i);
        }
    }

    private static class Task implements Runnable {

        private final Collection holder = new ArrayList<>();

        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                mayBeAdd(holder);
            }
        }
    }
}

7.1. マークの作成

アプリケーションがブレークポイントで停止し、スタックフレームからターゲットに到達できる場合、オブジェクトにマークを付けることができます。

それを選択し、F11Mark Objectアクション)を押して、ターゲット名を定義します。

image

7.2. マークを見る

これで、アプリケーションの他の部分でもカスタムオブジェクトラベルを確認できます。

imageimage

すばらしいのは、even if a marked object is not reachable from stack frames at the moment, we can still see its stateEvaluate Expressionダイアログを開くか、新しい時計を追加して、マークの名前の入力を開始することです。

IntelliJは、_DebugLabelサフィックスを付けて完成させることを提案しています。

imageimage

評価すると、ターゲットオブジェクトの状態が表示されます。

imageimage

7.3. 条件としてマーク

ブレークポイント条件でマークを使用することもできます。

imageimage

8. 結論

マルチスレッドアプリケーションのデバッグ中に生産性を大幅に向上させる多くの手法を確認しました。

これは通常、やりがいのある作業であり、ここではツールの支援の重要性を過小評価することはできません。