Roadmap & Progress
pg_ext_memcheck is being built in two phases. Phase 1 delivers an MVP that handles the most common PostgreSQL-specific memory bugs via SQL-queryable violation logs. Phase 2 adds a crash-isolated background worker and expanded stress scenario catalog.
Phase 1 — MVP
Completed 18 / 18 done — 100%- MemoryContext tree snapshot engine (context_walker)
- Snapshot diff algorithm (context leak detection)
- Executor hooks (ExecutorStart / ExecutorEnd)
- Planner hook (ALL mode — captures planning-phase allocations)
- Shared ring-buffer violation log (LWLock-protected)
- GUC parameters (gucs.c)
- ext_memcheck.flush_violations() SQL function
- Wrong-context allocation detection (wrong_ctx_alloc violations)
- ext_memcheck.begin() / ext_memcheck.end() session API
- violations SQL view (supported via flush_violations() & SELECT * FROM ext_memcheck.violation_log)
- ext_memcheck.run_scenario() stress runner
- Regression test suite
- Shmem boundary sentinel probe (shmem_probe.c)
- DSM segment lifecycle tracking (dsm_tracker.c)
- shmem_sentinel_probe scenario
- tx_abort_loop scenario
- growth_benchmark scenario
- Monotonic context growth / bloat measurement
Phase 2 — Extended Probes
In Progress 4 / 8 done — 50%- wrong_context_probe scenario
- BGWorker crash isolation harness (worker_harness.c)
- use_after_reset scenario (BGWorker crash-isolated)
- oom_simulation scenario (BGWorker crash-isolated)
- context_reset_storm scenario
- concurrent_backends scenario
- dsm_lifecycle_check scenario
- Named context matching (stable across restarts)
✅ complete · 🔧 in progress · ⬜ planned
Phase 1 scope
Section titled “Phase 1 scope”Phase 1 focuses on the bugs that hurt extension authors most often and that no external tool can catch:
- Context leak detection via before/after tree snapshots across query execution
- Wrong-context allocation detection — palloc() calls that accidentally land in
TopMemoryContextorCacheMemoryContext - Monotonic context-bloat detection — log-spaced checkpoint analysis with linear / superlinear shape classification and severity escalation, surfaced as
ctx_bloatviolations through thegrowth_benchmarkscenario - Shmem sentinel probing — sentinel bytes around shared memory allocations, verified post-invocation
- DSM lifecycle tracking — attach/detach lifecycle verification to catch leaked dynamic shared memory segments
- SQL-queryable violation log — all detected violations are written to a shared ring buffer and exposed via
ext_memcheck.flush_violations() - Session-level control API —
ext_memcheck.begin()/ext_memcheck.end()/ext_memcheck.run_scenario()to bracket test windows manually
Phase 2 scope
Section titled “Phase 2 scope”Phase 2 adds probes that require process isolation. Several items are already complete; the rest are planned.
Completed:
wrong_context_probescenario ✓ — focused wrong-context allocation check; runs onlycheck_wrong_context_allocdetection without thecontext_leakdiff, giving a clean isolated signal across N controlled repetitions- BGWorker crash harness ✓ —
use_after_resetandoom_simulationscenarios run in an isolated background worker; crash is confirmed via BGWorker exit code, not by propagating SIGSEGV to the test session
Planned:
context_reset_stormscenario — rapidly resets the currentMemoryContextbetween invocations to reveal extensions that hold raw pointers across context boundariesconcurrent_backendsscenario — spawns multiple background workers that simultaneously invoke the target function to stress shared data structures and LWLock usagedsm_lifecycle_checkscenario — runs the target function inside a DSM segment allocation/deallocation cycle and verifies correct attach/detach behavior
Known limitations
Section titled “Known limitations”| Limitation | Detail |
|---|---|
| Not production-safe | Instruments internals not designed for runtime inspection |
| PG 15+ only | Relies on MemoryContextData layout introduced in PG 15 |
| Context name collisions | Named context matching can fail if two contexts share a name |
| Single-backend view | Phase 1 does not observe allocations in other backend processes |
all-mode skips non-planned statements | In all mode the before-snapshot is taken in planner_hook. Cached/prepared statements re-executed via the extended protocol skip planning, and utility statements (DDL, SET, etc.) bypass both hooks. Use executor mode if you need every executor invocation bracketed. |