Debugging

PostgreSQL の install から gdb での debug をできる環境の作り方までを紹介します。

まずは PostgreSQL を git から clone してきます。

git clone git://github.com/postgres/postgres.git

次に configure から make install までします。この時に debug 用のオプションの指定を忘れてはいけません。 ここでは ~/local/postgresql-master に PostgreSQL をインストールする前提で説明します。

cd postgres/
./configure --prefix=~/local/postgresql-master --enable-cassert --enable-debug CFLAGS="-ggdb -Og -g3 -fno-omit-frame-pointer"
make -j4
make install

ここまでできたら data directory を初期化します。 encoding と locale の設定は好みの設定にすればよいですが、こだわりがなければ -E UTF8 --no-locale でよいと思います。

cd ~/local/postgresql-master/
mkdir -p var/{data,log}
./bin/initdb  -D ./var/data/ -E UTF8 --no-locale

PostgreSQL をすでに起動している場合は多重起動できるように設定ファイルを編集して接続を待ち受ける port を変更します。 今回は 5433 に変更するため下記設定を追加します。

port = 5433                             # (change requires restart)

ユーザーを作成します。適当に質問に答えます。

./bin/createuser --interactive -p 5433

開発用のデータベースを作成します。

./bin/createdb --port=5433 testdb

ここまでできたら、次のコマンドで PostgreSQL を起動します。

./bin/pg_ctl -D ./var/data/ -l ./var/log/postgres.log start

無事に起動していることが確認できたら、gdb を PostgreSQL の backend process に attach させます。 gdb で process に attach するためには process id を知る必要があり、SELECT pg_backend_pid(); で process id を取得できるため、結果を覚えておきます。この時 gdb でデバッグするために psql で接続したセッションはそのまま保持しつづけます。 次のコマンドで gdb を起動します。ここでは process id が 28282 の場合で説明します。

sudo gdb bin/postgres -p 28282

gdb で break point を張るときに gdb が symbol を見つけられるように bin/postgres を読み込んでおく必要があります。 後から読み込むときは file /path/to/file で読み込めます。 gdb で process に attach できたら、以下のコマンドで ExecResult 関数に break point をはります。

> b ExecResult

この状態で psql のセッションに戻り、SELECT 1 を実行します。 上手く break point がはれていれば psql の実行が止まるはずです。 gdb に戻り c で process を進めます。

(gdb) c
Continuing.

Breakpoint 1, ExecResult (node=node@entry=0x243ff00) at nodeResult.c:68
68      {
}
(gdb)

目的の関数 ExecResult で止まれば成功です。

以上が gdb で PostgreSQL を debug する方法です。gdb の使い方については別途調べてください。