1. 개요
PostgreSQL 소스코드 디버깅은 실행 중인 데이터베이스 서버 프로세스에 디버거를 붙여, SQL 한 문장이 parser, planner, executor를 거쳐 처리되는 흐름을 코드 레벨에서 추적하는 방법이다. Mac 환경에서는 기본 디버거가 lldb다. 그래서 PostgreSQL을 디버그 심볼이 포함된 상태로 빌드하고, VSCode에서 백엔드 프로세스에 attach하는 환경을 직접 구성해 보았다.
TIP
글을 쓰는 시점에는 (베타 제외) 17 버전까지 릴리스되어 있다. 본문은 17 버전 기준이다.
전체 흐름은 다른 운영체제(Linux, Windows)와 크게 다르지 않지만, Mac 에서는 gdb 대신 lldb(Low Level Debugger, LLVM 기반)를 써야 하므로 일부 설정과 명령어에 차이가 있다. 절차를 따라가면 아래 세 가지를 직접 해 볼 수 있다.
- PostgreSQL 소스 코드를 디버그 모드로 빌드하고 서버를 실행하는 방법
- VSCode 에서 lldb 로 PostgreSQL 백엔드 프로세스에 Attach 하는 방법
- breakpoint 를 설정하고 쿼리 실행 흐름을 코드 레벨에서 추적하는 방법
2. PostgreSQL 디버깅 환경 구성
2.1. PostgreSQL 소스 코드 가져오기
PostgreSQL 은 GitHub 에 공식 미러를 제공하지만, 실제 원본 소스는 별도 저장소에서 관리된다. 따라서 GitHub 가 아닌 PostgreSQL 자체 Git 저장소를 이용해야 한다.
git clone https://git.postgresql.org/git/postgresql.git
cd postgresqlclone 하면 기본 master 브랜치다. 특정 버전을 디버깅하려면 해당 브랜치/커밋으로 checkout 한다.
## 17 버전 STABLE checkout
git checkout REL_17_STABLE && git pull
## 특정 마이너 버전 checkout
git checkout REL_17_62.2. PostgreSQL 빌드
빌드에 필요한 패키지부터 설치한다.
brew install icu4c
brew install pkg-configPostgreSQL 공식 빌드 절차에 맞춰 빌드 전 configure 를 실행한다.
PG_VERSION=17
./configure \
--prefix=$HOME/postgres/pg${PG_VERSION} \
--enable-cassert \
--enable-debug CFLAGS="-ggdb -O0 -fno-omit-frame-pointer" CPPFLAGS="-g -O0" \
--with-includes=$(brew --prefix icu4c)/include \
--with-libraries=$(brew --prefix icu4c)/lib \
PKG_CONFIG_PATH=$(brew --prefix icu4c)/lib/pkgconfig옵션 설명:
--prefix: PostgreSQL 설치 경로--enable-cassert: 내부C Assert구문 활성화--enable-debug: 디버그 빌드 활성화CFLAGS:-ggdb(디버깅 심볼),-O0(최적화 비활성화),-fno-omit-frame-pointer(스택 추적 용이)CPPFLAGS:-g(디버그 심볼)--with-includes/--with-libraries:icu4c헤더/라이브러리 경로PKG_CONFIG_PATH:pkg-config라이브러리 탐색 경로
configure 가 끝나면 src/Makefile.global 이 생성된다. 의도한 옵션(특히 -g, -O0)이 반영됐는지 확인한다. 빠지면 디버깅 중 변수 값을 못 보는 문제가 생긴다(경험담).
grep -E '^(CFLAGS|CPPFLAGS) = ' src/Makefile.globalCPPFLAGS = -isysroot $(PG_SYSROOT) -g -O0 -I/opt/homebrew/opt/icu4c@77/include
CFLAGS = -Wall ... -g -ggdb -O0 -fno-omit-frame-pointer이제 빌드한다. --prefix 로 지정한 $HOME/postgres/pg17 에 결과가 생성된다.
make && make installWARNING
CFLAGS 와 CPPFLAGS 에 -g -O0 를 반드시 포함해야 한다. 빠지면 디버깅 시 변수 값을 확인할 수 없다.
2.3. PostgreSQL 서버 실행
initdb 로 PGDATA(데이터 디렉터리)를 생성한다.
$HOME/postgres/pg17/bin/initdb -D $HOME/postgres/pgdata/pg17서버 실행 전 $HOME/postgres/pgdata/pg17/postgresql.conf 에서 port, max_connections 등 주요 설정을 확인한다. 이제 서버를 실행하고 접속한다.
$HOME/postgres/pg17/bin/pg_ctl -D $HOME/postgres/pgdata/pg17 -l $HOME/postgres/pgdata/pg17/logfile start
## waiting for server to start.... done / server started
$HOME/postgres/pg17/bin/createdb -p 5432 test
$HOME/postgres/pg17/bin/psql -p 5432 testNOTE
$HOME/postgres/pg17/bin 을 매번 지정하는 건 번거롭다. 환경 변수로 등록할 수도 있지만, 여러 PostgreSQL 버전을 동시에 디버깅하면 경로가 충돌할 수 있어 추천하지 않는다.
3. VSCode 디버깅 환경 설정
VS Code 디버거 설정은 프로젝트별 또는 전역으로 적용할 수 있다. 이 글은 전역 설정을 기준으로 한다.
NOTE
프로젝트별로 설정하려면 소스 경로에 .vscode/launch.json 을 만들고 아래 내용을 추가한다.
- Command + Shift + P 로 명령 팔레트를 연다.
settings.json을 검색해 Preferences: Open User Settings (JSON) 을 선택한다.
settings.json 열기
settings.json에 아래를 추가한다.
VSCode 전역 launch 설정 보기
"launch": {
"version": "0.2.0",
"configurations": [
{
"name": "(lldb) Attach DB - PostgreSQL 17",
"type": "cppdbg",
"request": "attach",
"program": "${env:HOME}/postgres/pg${input:pg_version}/bin/postgres",
"MIMode": "lldb"
}
],
"inputs": [
{
"id": "pg_version",
"type": "promptString",
"description": "Enter the PostgreSQL Version",
"default": "17"
}
]
}- 서버 접속 후
SELECT pg_backend_pid();로 프로세스 PID 를 확인한다.
SELECT pg_backend_pid();
pg_backend_pid
----------------
85770
(1 row)- fn + F5 또는 Run and Debug → (lldb) Attach DB - PostgreSQL 17 로 디버거를 실행하고, 버전과
pg_backend_pid값을 입력한다.
lldb attach 실행
NOTE
MIMode 를 lldb 로, request 를 attach 로 설정해야 실행 중인 PostgreSQL 백엔드 프로세스에 연결된다.
4. 디버깅 테스트
- 쿼리 실행 함수
exec_simple_query를src/backend/tcop/postgres.c에서 찾아 breakpoint 를 설정한다.
exec_simple_query breakpoint
psql에서 쿼리를 실행한다.
CREATE TABLE test(id bigint not null generated by default as identity, name text);- breakpoint 가 정상 트리거되는 것을 확인할 수 있다. 이제 디버깅하며 PostgreSQL 동작 원리를 코드 레벨에서 학습할 수 있다.
breakpoint 가 트리거되어 멈춘 디버깅 화면
5. 마무리
| 단계 | 핵심 내용 |
|---|---|
| 소스 코드 준비 | PostgreSQL 공식 Git 저장소에서 clone 후 원하는 버전 checkout |
| 디버그 빌드 | configure 시 -g -O0 옵션 반드시 포함(최적화 비활성화) |
| 서버 실행 | initdb 로 PGDATA 생성 후 pg_ctl 로 기동 |
| VSCode 설정 | lldb · attach 모드로 백엔드 프로세스 PID 에 연결 |
| 디버깅 | breakpoint 설정 후 쿼리 실행으로 코드 흐름 추적 |
TIP
디버거로 PostgreSQL 의 동작 구조를 코드 레벨에서 직접 추적하며 실행 과정을 학습할 수 있다.