debugginglisted
Install: claude install-skill matejformanek/postgres-claude
# debugging
PostgreSQL is a **multi-process** server, not threaded: the postmaster
forks a fresh backend per connection. That single fact dictates the whole
debugging workflow. [verified-by-code; see `source/src/backend/postmaster/postmaster.c`,
and `.claude/skills/build-and-run/SKILL.md` line 59–63]
## 1. Build first
Debugging only makes sense against a debug build. See
`.claude/skills/build-and-run/SKILL.md` — `--buildtype=debug -Dcassert=true`.
`debug` (not `debugoptimized`) keeps locals and inline frames readable.
[verified-by-code; build-and-run/SKILL.md line 33]
The upstream FAQ recommends `CFLAGS="-ggdb -Og -g3 -fno-omit-frame-pointer"`
for autoconf builds — `-Og` keeps reasonable perf while preserving frames.
[from-wiki: Developer_FAQ]
## 2. The attach pattern (most common workflow)
**Project shortcuts.** In this repo, `/pg-attach` automates the held-PID
grab and prints the exact `lldb -p <pid>` line ready to paste; `/pg-tail-log`
follows `dev/data-debug/server.log` (where `pprint` and `elog` output land).
Use them.
The postmaster itself never executes your query. Attach to the **backend**
that handles your session. The key footgun: a one-shot
`psql -tAc "SELECT pg_backend_pid()"` closes the connection immediately,
so the backend you "got the PID of" is already gone by the time you read
the output. You need a **held** backend — one whose connection stays open
long enough for you to attach.
### The held-PID pattern (works from a script)
Open a backend that hol