GNUデバッグって何

ものすごく簡単に言うと, プログラムのバグを見つけるためのツールです.

何がうれしいか

  • 特定の箇所でプログラムを停止させて, 変数の中身を確認できる

具体的にはこんな感じです.

alt text

プログラム動作中に, 今の変数の中身を確認できるので, どこでバグが発生するか/どの変数の処理が誤っているかを特定しやすくなります.

VSCode上でGNUデバッグを扱う(ついでにF5を押してデバッグできるようにする)

こんな感じで競技プログラミング用とかのフォルダを作成&&移動

mkdir atcoder-submit

VSCode上からフォルダを開きなおします. ctrl + k ->ctrl + o なんかが楽です. \ なおこのモードでデバッグするには, VSCode上で設定したフォルダを開く必要があります.

開きなおした後, こんな感じの画面を開き, launch.jsonファイルを作成しますをクリック

alt text

launch.jsonというファイルができるので, 中身を以下の形に上書き

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "g++ - アクティブなファイルのビルドとデバッグ",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}/${fileBasenameNoExtension}",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "gdb の再フォーマットを有効にする",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "C/C++: g++ build active file",
            "miDebuggerPath": "/usr/bin/gdb"
        }
    ]
}

追加で, 手動でもコマンドでもなんでもいいので, .vscodeディレクトリの中に, tasks.jsonというファイルを作成し, 以下の内容で上書き

{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: g++ build active file",
            "command": "/usr/bin/g++",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "${file}",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}",
                "-std=gnu++20",
                "-Wall",
                "-Wextra",
                "-O0"      
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "AtCoder用ビルドタスク"
        }
    ]
}

ディレクトリ構成はこんな感じになれば大丈夫

.vscode─.
|       ├── launch.json
|       └── tasks.json
<その他>

後は実際にC++ファイルを開いて, F5実行できればOK

デバッガの触り方

F5でプログラムを開始する前に, ブレイクポイントという, ここで停止してね的なものを作成しておく. といってもこれは簡単で, 停止させたい行の左側をクリックするだけです. 赤い丸の箇所で止まる感じです. alt text

で後はF5で実行してみる

ブレイクポイントに到達すると, こんな感じに alt text

左側の領域に, 変数の中身が表示されるので, ここで変数の中身を確認できます.

で, デバッグ上での操作として, 下記のことができます.

機能名ショートカット何が起こるか
続行F5プログラムを実行し、ブレイクポイントに到達するまで停止しない
停止Shift + F5デバッグを停止する
単一ステップF10一行ずつ実行する
呼び出しステップF11関数の内部に移動して実行する
戻るShift + F11関数から戻る

競技プログラミングだと, F5とF10を使うことが多いです.

実際に使ってみる

こういう実装をバグらせやすい問題とか実装問題だと結構使えるかと思います.

ABC044 B - 美しい文字列 ABC048 B - Between a and b … ABC308 A - New Scheme

ブレイクポイントの一括削除

あまりにもブレイクポイントを多くつけて放置するとバグった経験があるので一応共有 alt text

図のような感じで, ブレークポイントの一括削除を押すと全部消せます.

余談・追加設定など

ちなみに, .vscode/settings.jsonに以下の内容を追加することで, エディタ上に変数の中身を表示させることができます.

{
  "editor.inlayHints.enabled": "on",
  "C_Cpp.inlayHints.autoDeclarationTypes.enabled": true,
  "C_Cpp.inlayHints.autoDeclarationTypes.showOnLeft": true,
  "C_Cpp.inlayHints.parameterNames.enabled": true,
  "C_Cpp.inlayHints.referenceOperator.enabled": true,
  "debug.inlineValues": "on",
  "debug.inlineValues.showNoFrameWarning": false,
  "C_Cpp.debugger.useBacktrace": "never",
  "editor.hover.enabled": "on",
  "debug.toolBarLocation": "docked"
}

こういう感じになる.

alt text

その他いろいろ設定できるので試してみてください(丸投げ)