On Fri, Jul 17, 2026 at 04:15:15PM +0200, Alex Masterov wrote:
> The assertion in issue #3 (ent->entry_ref != NULL, pgstat_shmem.c) also has
> a separate trigger I'd like to report — a different code path that poisons
> the same hash in pgstat_get_entry_ref_cached().
> pgstat_get_entry_ref_cached() inserts a zero-filled hash slot — entry_ref
> == NULL — before allocating memory for it. If MemoryContextAlloc() fails
> with OOM it longjmps out, leaving the NULL slot permanently poisoned in
> pgStatEntryRefHash. The hash is backend-local and cross-transaction, so
> abort does not clean it up.
> 
> Crash vectors:
> - Debug builds: backend exit hits Assert(ent->entry_ref != NULL) in
> pgstat_release_matching_entry_refs()
> - Release builds: any GC pass (DROP TABLE etc.) causes
> pgstat_gc_entry_refs() to unconditionally dereference the NULL → SIGSEGV
> 
> This is the backend-local sibling of the shared/DSA-path issue fixed in
> 8191e0c16a. Present since 5891c7a8ed8 (2022); affects PG15, PG17, PG18, and
> master.

Yeah, I can buy this one.  MemoryContextAlloc() would fail an longjmp
on OOM, so we'd better keep the backend data clean.  Perhaps we should
just use the Extended() flavor to bypass the failure and do cleanup
actions..  Will look later.
--
Michael

Attachment: signature.asc
Description: PGP signature

Reply via email to