もうprintlnデバッグは卒業。VSCodeで始めるRust実践デバッグ
はじめに
突然ですが、Rustでプログラムを書いていて、こんな経験はありませんか?
println!("ここまで到達");
println!("変数xの値: {:?}", x);
println!("デバッグ1");
println!("デバッグ2");
// ...あとでこれ消さないと...
println!でのデバッグは手軽ですが、コードが散らかり、デバッグ後に削除し忘れることも。
というか削除が面倒ですよね。
そんな時はVSCodeのデバッガーを使えば、コードを一切変更せずに変数の値を確認でき、問題を素早く解決できます。
この記事では、VSCodeを使ってRustプログラムを効率的にデバッグする方法を実践的に解説します。
そもそもデバッグとは?
デバッグ機能を使うと、以下のことができます。
- コードを1行ずつステップ実行して処理の流れを追跡
 - 任意の行で実行を一時停止(ブレークポイント)
 - 変数の値をリアルタイムで確認
 - 関数呼び出しのスタックを追跡してエラー箇所を特定
 - 式を評価して計算結果を確認
 
要はprintln!を書く必要がなく、プログラムを停止させながら内部の状態を自由に観察できるのが良いです。
環境構築
1. 必要なツールのインストール
まず、以下のツールがインストールされていることを確認してください:
- Rust (rustup経由でインストール)
 - Visual Studio Code
 
2. VSCode拡張機能のインストール
VSCodeで以下の拡張機能をインストールします。
必須: rust-analyzer
rust-analyzerはRustの言語サポートを提供し、デバッグ機能も統合されています。
- VSCodeの拡張機能タブ(Ctrl+Shift+X)を開く
 - 「rust-analyzer」を検索してインストール
 
以下のようなものです。(小学生の時に流行ったドラゴンのエプロンを思い出します)

必須: デバッガー拡張機能
OSに応じて以下のいずれかをインストール
macOS / Linux の場合
- CodeLLDBを検索してインストール
 
Windows の場合
- CodeLLDB または C/C++ (Microsoft製)をインストール
 - 両方試して、動作する方を使用してください
 
最も簡単な方法: CodeLens でデバッグ
なぜか自分の環境ではエラーが出ましたが一応紹介。(何回か繰り返すと動作する)
rust-analyzerをインストールすると、最も簡単にデバッグを開始できる機能が使えます。
手順
- Rustプロジェクトを開く
 - 
main.rsを開くと、main関数の上に「Debug」というリンクが表示されます 
// ↑ この上に「Debug | Run」と表示される
fn main() {
    println!("Hello, world!");
}

- 「Debug」をクリックするだけでデバッグが開始されます。
 
この方法なら、設定ファイルを作成する必要もありません。
初めてデバッグを試すときは、まずこの方法もありかもです。
本格的なデバッグ設定: launch.json
より細かい設定やカスタマイズが必要な場合は、launch.jsonを作成します。
細かいデバッグしたい人は調べてみてください。
今回ここをすると本筋から外れそうなので省略します。
サンプルプロジェクトの準備
cargo new debug_example
cd debug_example
code .  # VSCodeで開く
デバッグの実践
サンプルコードの準備
src/main.rsを以下のように編集します
fn main() {
    let numbers = vec![1, 2, 3, 4, 5];
    let sum = calculate_sum(&numbers);
    
    println!("合計: {}", sum);
    
    let doubled = double_numbers(&numbers);
    println!("2倍にした結果: {:?}", doubled);
}
fn calculate_sum(numbers: &[i32]) -> i32 {
    let mut total = 0;
    for &num in numbers {
        total += num;
    }
    total
}
fn double_numbers(numbers: &[i32]) -> Vec<i32> {
    numbers.iter().map(|&x| x * 2).collect()
}
ブレークポイントの設定
- デバッグを開始したい行番号の左側をクリック
 - 赤い点(ブレークポイント)が表示されます
 - 例: 
let sum = calculate_sum(&numbers);の行にブレークポイントを設定 
デバッグの開始方法
以下のいずれかの方法でデバッグを開始
- 方法1: 関数の上に表示される「Debug」リンクをクリック
 - 方法2: F5キーを押す
 - 方法3: 「実行とデバッグ」パネルから開始ボタンをクリック
 
自分はいつも「方法2」でやってます。
実行するとプログラムがブレークポイントで停止します。
デバッグコントロール
デバッグ中に使用できる主なショートカットをまとめました。
| 操作 | キー | 説明 | 
|---|---|---|
| 続行 | F5 | 次のブレークポイントまで実行 | 
| ステップオーバー | F10 | 現在の行を実行して次へ(関数には入らない) | 
| ステップイン | F11 | 関数の中に入る | 
| ステップアウト | Shift+F11 | 現在の関数から抜ける | 
| 再起動 | Ctrl+Shift+F5 | デバッグを最初から開始 | 
| 停止 | Shift+F5 | デバッグを終了 | 
変数の確認方法
デバッグ中は複数の方法で変数を確認できます
1. 変数パネル
左側の「変数」セクションに現在のスコープ内の全変数が表示されます。
2. ホバー
コード上の変数にマウスカーソルを合わせると、値がポップアップ表示されます。
3. ウォッチ式
「ウォッチ」セクションに式を追加して、常に監視できます。
例: numbers.len(), total * 2
4. デバッグコンソール
下部のデバッグコンソールで、簡単な式を評価できます。ただし、複雑なRust式は評価できない場合があります。
ちょっと深掘りデバッグテクニック
条件付きブレークポイント
特定の条件を満たしたときだけ停止するブレークポイントを設定できます。
設定方法:
- ブレークポイントを右クリック
 - 「ブレークポイントを編集」を選択
 - 条件式を入力(例: 
i == 50,total > 100) 
使用例:
for i in 0..100 {
    // ここにブレークポイントを設定し、条件に「i == 50」を設定
    // すると、iが50のときだけ停止する
    println!("{}", i);
}
ログポイント
実行を止めずに、特定の行を通過したときにログを出力できます。
設定方法:
- 行番号を右クリック
 - 「ログポイントを追加」を選択
 - 出力したいメッセージを入力
- 例: 
"iの値: {i}, totalの値: {total}" 
 - 例: 
 
これはprintln!を書かずに同じ効果が得られる優れた機能ですが、ちょっと扱いづらいかもです。
VScodeのデバッグコンソールに表示されます。
テストのデバッグ
単体テストもデバッグできます。
#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_calculate_sum() {
        // ↑ この上に「Debug」リンクが表示される
        let numbers = vec![1, 2, 3];
        assert_eq!(calculate_sum(&numbers), 6);
    }
}
テスト関数の上に表示される「Debug」をクリックすると、テストをデバッグモードで実行できます。
よくある問題と解決方法
問題1 変数の値が表示されない
原因 コンパイラの最適化により変数が削除されている
解決策 Cargo.tomlに以下を追加
[profile.dev]
opt-level = 0
debug = true
通常、dev プロファイルはデフォルトでこの設定になっていますが、念のため確認してください。
問題2 ブレークポイントが灰色で無効になる
原因 コードがコンパイルされていない、またはそのコードパスが実行されない
解決策
- プログラムを一度ビルドしてから再試行
 - 
cargo clean && cargo buildで完全にリビルド - そのコードが実際に実行されるパスにあるか確認
 
問題3 デバッガーが起動しない
原因 拡張機能の競合や設定ミス
解決策
- CodeLLDBとC/C++拡張を両方インストールしている場合、片方を無効化
 - VSCodeを再起動
 - 
launch.jsonのtypeが正しいか確認(lldbまたはcppvsdbg) 
問題4: Windowsで動作しない
原因 CodeLLDBがWindows環境で不安定な場合がある
解決策 C/C++拡張を使用し、上記のcppvsdbg設定を使用してください。
println!デバッグ vs デバッガー
最後に、それぞれの使い分けを整理しておきます。
println!デバッグが向いている場合
- 非常にシンプルな確認
 - 長時間実行されるプログラムのログ収集
 - 本番環境での動作確認
 
デバッガーが向いている場合
- 複雑なロジックの動作確認
 - バグの原因特定
 - データ構造の詳細な検査
 - ステップ実行で処理の流れを追跡したい場合
 
基本的には、開発中はデバッガーを積極的に使うことをおすすめします。
まとめ
VSCodeでのRustデバッグは、適切な拡張機能をインストールすれば簡単に始められます。
クイックスタート
- rust-analyzerとCodeLLDBをインストール
 - Rustファイルを開く
 - 関数の上の「Debug」をクリック
 
主な機能
- ブレークポイントで実行を停止し、変数を確認
 - ステップ実行で処理の流れを追跡
 - 条件付きブレークポイントで効率化
 - ログポイントでコードを変更せずにログ出力
 
最初は慣れないかもしれませんが、一度使い始めるとprintln!デバッグには戻れなくなるはずです。ぜひ積極的に活用して、効率的な開発を楽しんでください!
Discussion