君はVS Codeのデバッグの知られざる機能について知っているか

# はじめに
こんにちは、kenです。
GWに「暇だな～～、こんな日はVS Codeの公式ドキュメントを読むか！w」と思って何気なく読んでたら[デバッグ](https://code.visualstudio.com/docs/editor/debugging)に関して知らない機能がいくつかあったので、今回はそれをご紹介したいと思います。
おそらく今から紹介する機能はあまり知られてないと思います。もし全部知ってたらVS Code完全理解者なので誇ってください。（！？）

以下に記載する内容はVS Codeの公式ドキュメントのDebuggingという章を参考にしています。

https://code.visualstudio.com/docs/editor/debugging

## 注意
:::note warn
* これから紹介する機能は言語によって使えたり、使えなかったりします。
* 今から紹介する機能のデモはすべてPythonで行おうかと思ったのですが、上記の理由からPythonではサポートされていない機能についてはJavaScriptやC++で代用しました。
:::


# デバッグで使える便利な機能

## ログポイント機能
行を指定しログポイントを追加すると、その行を訪れたタイミングでログを出力できます。
もちろんログ内には`{式}`という書式を使えば式も含めることもできます。
**既存のコードに修正を加えることなく、ログを出力できるのは嬉しいですね！！**
これで **「プリントデバッグしたprint行を消し忘れてPRあげちゃった……」** みたいなことがなくなりそうです。

ログポイントを設定する方法は、ログポイントを出したい行の行番号の左側で右クリックし「ログポイントを追加」を選択。その後出したいログの内容を入力するだけです。
追加したログポイントは赤い<font color='red'>◆</font>のマークで表され、出力したログはデバッグコンソールから確認できます。
![logpoint.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1649218/2197bb27-2634-a0fb-f65f-c2124960bc52.gif)
上の例では`1`から（引数で受け取った）`N`までの総和を計算するプログラムのなかで、その段階的な計算結果をログとして出力させています。
## ヒットカウント機能
行を指定しヒットカウント機能を使ってブレークポイントを設定すると **「その行をN回目に訪れたタイミングでブレークポイントを発動させる」** といったことが可能になります。
これで **「for文の中の`i == 15`のときの挙動がみたいんだよ～～（ｶﾁｶﾁｶﾁｶﾁ）」** みたいにひたすらデバッグの再生マークを連打する虚無タイムからは卒業できそうです。

ヒットカウント機能を使ってブレークポイントを設定する方法は以下の通りです。
まず、ブレークポイントを設定したい行の行番号の左側で右クリックします。次に、「条件付きブレークポイントを追加」を選択し、プルダウンメニューから「ヒット カウント」を選びます。最後に、何回目にその行を訪れた時にブレークポイントが発動するかを指定して設定を完了します。
![Conditional_breakpoints_hit.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1649218/ceb7d864-b6cb-d343-c1c3-44ec575e5f99.gif)
上の例では（先ほどと同じ）プログラムの中で`res += i`の行を3回目に訪れるタイミングでブレークポイントが発動するようにヒットカウント機能を設定しています。
## 条件付きブレークポイント機能
条件付きブレーク機能では、ブレークポイント設定時に条件式を入力し、**その条件式がtrueになったタイミングでブレークポイントが発動するようにできます。**
**「この値が〇〇になったタイミングでなにかバグってるはずなんだよな～～」** という場合に重宝しそうです！！

条件付きブレークポイントは、ブレークポイントを設定したい行の行番号の左側で右クリックをし「条件付きブレークポイントの追加」を選択。その後プルダウンメニューから「式」を選び、そこに条件式を入力することで設定できます。
![Conditional_breakpoints_eq.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1649218/5cd063f1-9576-0b33-6add-87fec36ddc6a.gif)
上の例では条件式として`res == 15`を設定しています。するとデバッグ実行時に`res == 15`が`true`となったタイミング、すなわち`i == 5`まで計算し終わったタイミング[^1]でブレークポイントが発動しています。
[^1]: 1+2+3+4+5=15であることから
## インラインブレークポイント機能
ブレークポイントは行単位ではなく、**ステートメント単位で設定することもできます。**
ひとつの行に複数のステートメントが存在してる場合に便利です。

インラインブレークポイントはステートメントの先頭で`Shift + F9`を押すことで設定できます。
![debug_inline_breakpoints.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1649218/d8a41185-3a59-ce4c-58d3-10902edcde02.gif)
上の例では
1. 変数`a`を初期化する
1. `a`をインクリメントする
1. `a`を出力する

という3つのステートメントが含まれていますが、そのひとつひとつにブレークポイントを設定しているため、そのそれぞれでブレークポイントが発動しています。
## 関数ブレークポイント機能
関数ブレークポイント機能を使えば **「指定した関数名に到達したタイミングでブレークポイントを発動させる」** といったことができます。
**「呼び出されてる関数名はわかるけど、それがどこで書かれてるのかわからん！！」** という場合に使えそうです。

関数ブレークポイントはブレークポイントセクションヘッダーの+ボタンを押して関数名を入力することで作成できます。作成すると、関数ブレークポイントはブレークポイントセクションに赤い<font color='red'>▲</font>で表示されます。
![debug_function_breakpoints.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1649218/0df04552-60a0-f1b1-13a1-6d47797440a7.gif)
上の例では、`sum_to_N`という関数名で関数ブレークポイントを設定したことで、（`sum_to_N`の関数内部にブレークポイントを設定していないのにもかかわらず）実際に`sum_to_N`に到達したタイミングでブレークポイントが発動しています。
## データブレークポイント機能
データブレークポイント機能を使うと、**指定した変数の値が変更/読み取り/アクセスされた場合にブレークポイントを発動させることができます。**
**「この値いつ変更されてんねん！」** という場合に一つずつステップ実行する必要がなくなるので便利です。

データブレークポイント機能はデバッグセッション時の変数セクションから変数を選んで右クリックし、「値が変更されたときに中断する」を選択することで設定できます。
![debug_data_breakpoints.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1649218/778687de-943a-e959-2c75-9982364fccee.gif)
上のGIF画像で動かしているのは、0から100までの5の倍数の総和を計算するプログラムです。
最初に変数`res`にデータブレークポイントを設定したため、`res`が更新されるタイミング、すなわち`i`が5の倍数であるときに限ってブレークポイントが発動しています。
## デバッグコンソール
デバッグコンソールでは、**デバッグ中にプログラムの実行を制御し、コード内の変数や式の評価を行うことができます。** 
つまり、ステップ実行中の変数の状態をより詳細に確認することができるということです。

デバッグコンソールを使う方法は、デバッグセッション時にデバッグコンソールに移動して確認・評価したい変数や式を入力するだけです。
![debug_console.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1649218/62538bc8-e1eb-0c2a-9ce1-f285628c984c.gif)
上の例では、ステップ実行中に式をいろいろ入力してデバッグコンソールに出力させています。デバッグ中の変数の状態で`i + 10`などの式が評価されているのがわかると思います。
（最初`i`を出力させようとしたときはまだ`i`が宣言される前だったのでエラーが出ています。）

# おわりに
今回はVS Codeのデバッグについて、あまり知られてないと思われる機能をご紹介しました。かなり痒いところまで手が届く機能ばかりで、やはり何に関しても公式のドキュメントを読むのは大事だなと感じさせられました…
間違いなどありましたらコメントにてご指摘いただけますと幸いです。
最後まで読んでいただきありがとうございました！！