前提
Windows10+VSCodeの環境でRustを書く上でデバッグ接続できる環境を整える。
いくつかプラグインや設定の選択肢があって迷ったけど、なんとか欲しかった環境が整ったのでそのメモ。
環境
Windows10
VSCode: 1.25.1
Rust: 1.29.0-nightly
rustup: 1.13.0
ツールチェイン: x86_64-pc-windows-msvc
できるようにすること
- panic時に停止して、コールスタックを見る
- コールスタックのソースファイルや行番号の確認や、そこへのジャンプ
- ブレークポイントを置いて停止
- 停止時にローカル変数の中身を確認
- 停止後にステップ実行
使用したプラグインと設定
C/C++ for Visual Studio Code
C++用のプラグインだが、Rustのデバッグにも使える。
設定ファイル
.vscode/launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(Windows) Launch",
            "type": "cppvsdbg",
            "request": "launch",
            // 以下はテストコードをデバッグするための設定
            "preLaunchTask": "build_for_test",
            // cargo testで出力されるexeファイル名は決定的ではないので、ファイル名が変わるごとに書き換える必要がある
            // 詳しくは以下
            // https://github.com/rust-lang/cargo/issues/1924
            "program": "./target/debug/lib-1adc6a69d090234d.exe", 
            "args": ["--nocapture"],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "internalConsoleOptions": "openOnSessionStart",
            "sourceFileMap":{
                // 以下は環境に合わせて変更が必要
                "c:/projects/": "${env:HOMEPATH}/.rustup/toolchains/nightly-x86_64-pc-windows-msvc/lib/rustlib/src/",
            },
            "logging": {
                "trace": false,
                "exceptions": false,
                "moduleLoad": false,
                "traceResponse": false,
                "engineLogging": false,
                "programOutput": true,
            }
        }
    ]
}
.vscode/tasks.json
{
    "version": "0.1.0",
    "command": "cargo",
    "isShellCommand": true,
    "tasks": [
        {
            "taskName": "build",
            "isBuildCommand": true,
            "showOutput": "always",
            "problemMatcher": {
                "owner": "rust",
                "fileLocation": [
                    "relative",
                    "${workspaceRoot}"
                ],
                "pattern": [
                    {
                        "regexp": "(error|warning)(?:\\[(.*)\\])?: (.*)",
                        "severity": 1,
                        "code": 2,
                        "message": 3
                    },{
                        "regexp": "-->\\s+([^:]*):(\\d+):(\\d+)",
                        "file": 1,
                        "line": 2,
                        "column": 3
                    }
                ]
            }
        },
        {
            "taskName": "clean",
            "showOutput": "always"
        },
        {
            "taskName": "build_for_test",
            "command": "cargo",
            "args": ["test", "--no-run"],
            "isTestCommand": true,
            "showOutput": "always",
            "problemMatcher": {
                "owner": "rust",
                "fileLocation": [
                    "relative",
                    "${workspaceRoot}"
                ],
                "pattern": [
                    {
                        "regexp": "(error|warning)(?:\\[(.*)\\])?: (.*)",
                        "severity": 1,
                        "code": 2,
                        "message": 3
                    },{
                        "regexp": "-->\\s+([^:]*):(\\d+):(\\d+)",
                        "file": 1,
                        "line": 2,
                        "column": 3
                    }
                ]
            }
        }
    ]
}
デバッグは、「デバッグ->デバッグの開始」から開始できる。
他に試したプラグイン
LLDB
- 現状、Windowsではツールチェインがi686-pc-windows-gnuでないと動かない。
- ブレークポイント、ローカル変数表示、ステップ実行などはできたが、標準ライブラリ内へのジャンプはソースコードではなくアセンブリの表示だった。
- launch.jsonでcargoのtestを直接指定できるので、実行ファイル名が変わる問題を回避できる。
WinDbg
- デバッグ接続自体は動いたが、標準出力が表示されなかった。チケットはあったものの放置されてる。