ぱと隊長日誌

ブログ運用もエンジニアとしての生き方も模索中

VS Code と GDB で PostgreSQL をデバッグする

概要

VS CodeGDBPostgreSQLデバッグする手法については、わかりやすいスライドが公開されています。

ただ、この資料では WSL (Ubuntu) 上で構築していたり、VS Code に慣れていないと戸惑う箇所がありました。

そこで、本記事は他の環境でも同様の手法でデバッグできることを示し、VS Code で戸惑いやすいポイントを解説します。

環境

Windows 10 の Hyper-VRed Hat Enterprise LinuxVM を構築します。この VMPostgreSQL をインストール・動作させ、Windows 10 の VS Code からデバッグできるようにします。

構成図を示します。
VS Code からデバッグする際の構成図

なお、このイメージ図では VS Code Server を省略しています。構築手順において意識せずに済むためです。

ホスト

OS Windows 10 Pro バージョン 22H2

Hyper-V

構成バージョン 9.2
OS Red Hat Enterprise Linux release 9.1

ソフトウェア

ソフトウェア バージョン
Visual Studio Code 1.75.0
PostgreSQL 15.1
GDB 10.2-10.el9

用語

本記事においては下記の略記を用います。

略記 名称
VS Code Visual Studio Code

構築手順

(1) VM構築

今回の記事では割愛します。

VM の構成バージョンを指定して作成したい場合は下記の記事を参照してください。
Hyper-V の仮想マシンで perf の "not supported" な項目を出力できるようにする - ぱと隊長日誌

(2) PostgreSQL + GDB 構築

PostgreSQLソースコードからインストールします。
基本的な手順は PostgreSQL マニュアルを参照してください。
第17章 ソースコードからインストール
※リンク先は現時点で日本語版かつ最新のバージョン 14 です。

以下で基本的な手順からの差分を示します。

PostgreSQL ビルド時にはデバッグ用のオプションを指定します。

# ./configure --enable-debug CFLAGS=-O0

GDB をインストールします。

# dnf install gdb

(3) VS Code インストール

VS Code の公式サイトからダウンロード・インストールします。
Visual Studio Code – コード エディター | Microsoft Azure

以下の拡張機能をインストールします。

(4) VS CodeSSH リモート接続する

VS Code の該当マニュアルを示します。
Developing on Remote Machines using SSH and Visual Studio Code

以下でポイントを説明します。

Ctrl+Shift+P でコマンドパレットを開き、「Remote-SSH:ホストに接続する...」をクリックします。
VS Code で SSH リモート接続する

テキストボックスに "user@host" の形式で入力します。例えば、"root@192.168.0.15" のようになります。
VS Code で接続先ホスト名とユーザー名を入力する

新しい VS Code のウィンドウが開きます。
初回接続時は接続先 OS の種類を聞かれますので、適宜選択します。
VS Code で初回接続時に接続先 OS を聞かれる

接続先ユーザーのパスワードを要求されるので入力します。
この後の手順でもパスワードを要求されることがあるので、同様に入力します。
VS Code でパスワードを入力する

Ctrl+K Ctrl+O でフォルダー(ディレクトリ)を開きます。ここでは PostgreSQLソースコードが格納されたフォルダーを指定します。
VS Code でフォルダを開く

フォルダーを信頼するか否か問われるので、「信頼する」を選びます。
VS Code でフォルダを信頼するか否か問われるダイアログ

(5) リモートホストVS Code拡張機能をインストールする

以下の拡張機能リモートホストにインストールします。

該当の拡張機能に「SSH: 192.168.0.15 にインストールする」のようなボタンが現れています。これをクリックしてインストールします。
VS Code で拡張機能をリモートホストにインストールする際のボタン

(6) PostgreSQLデバッグ対象を選択する

PostgreSQL の構造とソースツリー(3) | Let's POSTGRES
この記事同様に、"SELECT 1;" というクエリが ExecSelect 関数に至る様子を観察することにします。

PostgreSQLpsql で接続し、バックエンドのプロセス ID を確認します。

=# SELECT pg_backend_pid();

VS Code で任意の C ファイルを開きます。

Ctrl+Shift+D で「実行とデバッグ」を開きます。

「launch.json ファイルを作成します」というリンクをクリックします。
開いたフォルダーの直下に ".vscode" というサブフォルダーが作られ、そこに launch.json ファイルが格納されます。

launch.json ファイルの例を示します。

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "postgres",
            "type": "cppdbg",
            "request": "attach",
            "program":"/usr/local/pgsql/bin/postgres",
            "processId": 3400,
            "MIMode": "gdb",
            "miDebuggerPath": "/usr/bin/gdb"
        }
    ]
}

環境に応じて適宜書き換えます。"processId" は先ほど調べたバックエンドのプロセス ID を指定します。
VS Code の launch.json 編集画面

F5 を押すとデバッグが開始されます。

デバッガー画面のブレークポイントに "ExecResult" を追加します。

psql から "SELECT 1;" を実行してブレークポイントで停止すれば成功です。
VS Code でブレークポイントにて停止した画面

落とし穴

リモートホストVS Code拡張機能をインストールしないといけないのはなぜ?

VS Code のバックエンド (VS Code Server) が拡張機能を実行するためです。

VS Code のマニュアルから SSH 接続でリモート開発する際のアーキテクチャ概要図を示します。

Developing on Remote Machines using SSH and Visual Studio Code

VS Code はフロントエンド・バックエンドのプロセスが分離されています。

Visual Studio Code」がマルチプロセスで設計されているからだ。コードを入力するフロントエンドと、それ以外のバックエンド(拡張機能、ターミナル、デバッガーなど)のプロセスは分離されており、異なるデバイスに分けて動作させることもできる。

VS Code Server」はこのバックエンド部分のみを独立させ、1つのサービスとして利用できるようにしたものだ。CLIとして動作する仕組みになっており、ローカルの開発マシン、クラウド仮想マシンなど好きなところにインストールできる。

「VS Code Server」が登場 ~VS Codeのバックエンドを単体CLIに、フロントエンドにはWeb版が使える - 窓の杜

VS Code Server は SSH 接続時に自動でインストールされています。
VS Code Remote - SSH extension で Linux のリモートマシンに接続すると VS Code Server が自動でインストールされる - ぱと隊長日誌

launch.json ファイルを作れない

任意の C ファイルを開いた状態で「launch.json ファイルを作成します」リンクをクリックすれば作成できます。

コールスタックで「不明なソース」と表示される

VS Code のコールスタックで「不明なソース」と表示される

原因の一つとして考えられるのが、PostgreSQL コンパイル時のデバッグオプションを正しく指定していないことです。PostgreSQL を再ビルドしたのであれば、make distclean を実行したか確認してください。

再ビルド時の make distclean の必要性については下記記事を参照してください。
PostgreSQL のビルドで configure オプション変更時は make distclean を実行すべき - ぱと隊長日誌

デバッガーが動作しないので問題を切り分けたい

本記事の手順を踏んでいれば、PostgreSQL をインストールしたサーバに GDB もインストールしているはずです。なので、GDBデバッグできるか否かで問題をある程度切り分け可能です。GDB でのデバッグ手順は下記記事を参照してください。
PostgreSQL の構造とソースツリー(3) | Let's POSTGRES