JetBrains Riderで使用できる12のデバッグテクニック

本記事はJetBrains公式ブログより引用した内容となります。

## JetBrains Riderで使用できる12のデバッグテクニック
アプリケーションを壊すバグほど、ソフトウェア開発の流れを止めるものはありません。バグはソフトウェア開発の自然な一部ですが、それに費やす時間を最小限に抑えることは可能です。

この記事では、JetBrains Riderの機能セット内でバグを修正し、開発の流れに戻るための12のデバッグ機能とテクニックを紹介します。さあ、一緒にレベルアップしましょう！

## 1. インラインウォッチ  
デバッグのために変数を追加するためにコードをリファクタリングしたことはどれくらいあるでしょうか？
以下のコードを見てみましょう。

```csharp
var x = 1;
var y = 2;

Console.WriteLine($"{x} + {y} = {x + y}");
```

コードベースに`var result = x + y`を追加したくなるかもしれませんが、JetBrains Riderのデバッグ機能を使えば、それは必要ありません。デバッグセッション中に、使用したい値の後の任意の行を右クリックし、「**インラインウォッチの追加**」オプションを選択します。任意の式を入力すると、Riderがその評価結果をエディタ内に表示します。
![dotnet_howtos_20240129.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936166/f7b9ac85-6365-c93d-07e9-cf98ed28c17e.png)


すべてのインラインウォッチはデバッグセッションをまたいで保持されるため、次回の実行で前回の作業を活用することができます。

## 2. 戻り値
インラインウォッチと同様に、実行によって明示的に変数に設定されていない値を確認したい場合があります。戻り値は、開発者が追加情報を得るためにブレークポイントを追加する一般的な場所です。JetBrains Riderの場合、戻り値は自動的にインラインウォッチとして追加されます。
![dotnet_howtos_20240129-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936166/b1d3e691-bc5d-4cd5-bcb4-a81435ae52d5.png)

また、デバッガーツールウィンドウやその他のデバッグセッションの値にも、これらの値を表示します。
![dotnet_howtos_20240129-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936166/7561c802-472c-3faa-832e-b7691b468416.png)

## 3. スマートステップデバッグ
メソッド呼び出しを1行にチェーンする際、コールスタックを辿るのはまるで洞窟探検のように感じることがあります。重要な部分にたどり着くまで進んでいく必要があります。しかし、**スマートステップイン**を使うと、他のメソッドを飛ばして、常に正しいメソッドを選択することができます。
![dotnet_howtos_20240129-4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936166/f366f61f-54fe-7778-7959-ee24828f8c54.gif)

## 4. ブレーキングポイントオプション
どのアプリケーションでも、デバッグセッションでは多くのことが行われています。そのため、調査中に追加の情報が必要になることがあります。デバッガーツールウィンドウには、重なり合った2つのブレークポイントのアイコンが表示されます。このアイコンをクリックすると、「ブレークポイントのオプション」ウィンドウが開き、既存のブレークポイントを確認したり、ブレークポイントがどのように動作するかを設定したりできます。
![dotnet_howtos_20240129-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936166/c9336750-5e13-966b-5fa7-af33d1ce1e82.png)

このウィンドウを探索する価値があります。ここでの数分の投資が後で何時間もの節約につながることがあります。また、新しいブレークポイントを設定する際に「**Shift+クリック**」を使って、追加のオプションを表示することもできます。ブレークポイントダイアログの詳細については、[JetBrains Riderのドキュメント](https://pleiades.io/help/rider/Using_Breakpoints.html)を参照してください。
![dotnet_howtos_20240129-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936166/7c0b640e-ec4e-bdb6-67bb-4687a7cf97f0.png)

## 5. 実行ポインタをドラッグ
場合によっては、問題のあるコード行を再実行したりスキップしたりする必要があります。黄色の実行ポイントをドラッグすると、実行中のアプリケーションの実行パスを変更できます。この機能により、より少ない調査で問題が発生するタイミングと場所を絞り込むことができます。
![dotnet_howtos_20240129-7.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936166/c531da0f-9767-7865-11e4-54da4085f4ba.gif)

エディタ上でカーソルを合わせると、2つのアイコンも表示されます。最初の黄色いアイコンは「**ここまでスキップ**」機能を示しており、現在の実行行とターゲット行の間の行は実行されません。青い「ここまで実行」アイコンは、ターゲット行までのすべての行を実行します。これらは、カーソルを下にドラッグするよりも便利な場合があります。

## 6. 外部のデコンパイルされたコードのデバッグ
現在の.NET環境は以前よりオープンになっていますが、まだサードパーティのライブラリに依存している不運な方にとっては、ブラックボックス内で例外が発生するとフラストレーションが溜まります。JetBrainsのツールでは、デバッグ中にサードパーティのライブラリをデコンパイルし、例外を投げていると疑われるメソッドにステップインすることができます。「**Ctrl+クリック**」ショートカットを使うと、コードがデコンパイルされる必要があっても、そのシンボルを含むコードにジャンプできます。デコンパイル後は、ブレークポイントを設定して、「自分側の問題」か「相手側の問題」かを迅速に特定することができます。

## 7. 例外ブレークポイント
アプリケーションが突然終了した理由について頭を悩ませたことがある人は、あなただけではありません。その原因は通常、CLRまたは一般的な例外です。デバッグセッションが突然終了した場合は、ブレークポイントオプションウィンドウ内の**CLR例外ブレークポイント**および**例外ブレークポイントオプション**を確認してください。アプリケーションは、ディスクアクセスや不正なアクセス許可などの構成上の問題がある場合に、これらの例外を投げることがあります。この機能は、`catch`ブロックが例外を処理する前に停止するのにも役立ちます。
![dotnet_howtos_20240129-8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936166/c421cff9-ae1f-5cd1-453f-e7869df1cd1e.png)

## 8.静的メソッドの実行とデバッグ
JetBrains Riderを使えば、任意の静的メソッドを単独で実行することができます。静的メソッドを実行することで、自己完結的で再現可能な状況を作成し、実行時の問題を絞り込むのに役立ちます。パラメータのない`public static void`メソッドのガターにある「実行」ボタンを探してください。静的メソッドの実行設定は、コードベース内で再現可能なタスクを保存するための優れたツールでもあります。
![dotnet_howtos_20240129-9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936166/2f84df1c-7f0c-0318-84ed-5fd344d6f661.png)

## 9. ホットリロード
フィードバックループは高速なソフトウェア開発の中心であり、.NET**ホットリロード**を使用することで、開発者は他のエコシステムとは異なる反復的なプロセスを体験できます。**ホットリロード**を使用すると、実行中のアプリケーションに対してターゲットを絞ったコード変更を行い、リコンパイルや調査の中断なしに変更を反映させることができます。

## 10． メモリービュー
アプリケーションのメモリ領域に何があるかを知ることは、厄介なバグを追跡する際に戦いの半分を占めることがあります。JetBrains Riderの**メモリ**タブを使用すると、現在メモリに読み込まれているクラス、クラスの数、およびそれらが占めているメモリサイズを確認できます。このビューは、Dynamic Program AnalysisやdotMemoryなどの詳細なツールを補完する優れた概要を提供します。
![dotnet_howtos_20240129-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936166/15a6d449-21bd-c1db-ebaf-bfa9be7e1ef3.png)

## 11. スレッド固有のブレークポイント
一般的に、アプリケーションには複数のスレッドが同じコードセットを実行していることがあります。デバッガーツールウィンドウのスレッドビューでは、各スレッド内で実行されているコールスタックを確認でき、ブレークポイントをどこで停止させるべきか、いつ停止させるべきかを絞り込むのに役立ちます。
![dotnet_howtos_20240129-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936166/3175432d-053f-d246-b0a1-f73440f87e56.png)

スレッドを特定したら、ブレークポイントオプションウィンドウを使って、選択したコンテキストでのみブレークするように設定できます。
![dotnet_howtos_20240129-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936166/d215b741-f5e1-2bd6-5625-1ed823118c70.png)

デバッグ中にエディタ内の任意のブレークポイントを右クリックすることで、スレッドをすばやく設定することもできます。

## 12. DebuggerDisplayAttributeのサポート
複雑なクラス定義には多くのデータが含まれていることがありますが、ユーザーにとってわかりやすい情報は少ない場合があります。`DebuggerDisplayAttribute`を使用することで、JetBrains Riderで重要な情報をどのように表示するかをカスタマイズできます。
例えば、以下のコードを見てみましょう：
```csharp
using System.Diagnostics;

var result = new Result(1, 1);

Console.WriteLine(result);

[DebuggerDisplay("Math: {X} + {Y} = {Value}")]
public record Result(int X, int Y)
{
    public int Value => X + Y;
};
```

JetBrains Riderは、`DebuggerDisplayAttribute`を使用して、エディタおよびデバッグツールウィンドウ内に表示値をレンダリングします。
![dotnet_howtos_20240129-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936166/5eb8fea9-ac8b-d84e-7a2f-74a250b8f3d8.png)

重要な情報を見つけるためにデバッグ値を切り替えるのに時間を無駄にしている場合は、この機能を使うことを検討してください。

## ボーナス：予測デバッガー
分岐するコードは、頭の中で追跡するのが難しいものです。JetBrains Rider 2023.3では、待望の**予測デバッガー**機能が追加されました。現在の実行コンテキストをもとに、JetBrains Riderはコードの実行フローを予測し、特定のパスから得られる値を予測することができます。この機能は、変数の値や発生する可能性のある例外を事前に予測するのに役立ちます。
![dotnet_howtos_20240129-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936166/93840e77-6363-e005-e6ae-36f7e6dd1a9a.png)

## 結論
デバッグのワークフローを改善するためのさまざまなアプローチが詰まったツールボックスがあります。これらの機能はそれぞれ単独でも優れていますが、組み合わせることでさらに効果的です！バグは厄介ですが、デバッグがあなたの負担になる必要はありません。コメントで、どの機能が気に入ったか、どの機能をもっと使いたいかを教えてください。

いつも読んでいただき、JetBrains IDEに興味を持っていただきありがとうございます。