Craig Ringer
Craig Ringer

Reputation: 325051

Is there any way to name mempools in valgrind memcheck?

PostgreSQL makes heavy use of memory pools and, when Valgrind is enabled, supplies information about them to Valgrind using VALGRIND_CREATE_MEMPOOL etc.

Combined with incremental leak checking using client-requests like VALGRIND_DO_LEAK_CHECK and VALGRIND_DO_ADDED_LEAK_CHECK this is really useful for keeping track of memory use in a large, complex and long-lived program.

But: PostgreSQL has lots of caches whose lifetimes tend to span typical boundaries like transactions. It's generally fine for memory in such caches to appear to leak (for various reasons), but not always easy to identify if such memory is allocated in a cache context using only the stack.

So I'm looking for a way to show memory pool names in leak reports and filter on them in suppressions. Ideally something like

# Do not copy, this DOES NOT WORK
{
   my_suppression_name
   Memcheck:Leak
   match-leak-kinds: reachable
   pool:CacheMemoryContext           # <---- something like this
   fun:malloc
   fun:AllocSetAlloc
   fun:palloc
   fun:initStringInfo
   fun:apply_work
   ...
}

or in leak reports, like this:

... 6 (+6) bytes in 1 (+1) blocks are possibly lost in loss record 180 of 942
...    in mempool "CacheMemoryContext"                   <---- Like this
...    at 0x815FFC: MemoryContextAlloc (mcxt.c:771)
...    by 0x817680: MemoryContextStrdup (mcxt.c:1157)

I suspect the answer is "no" since the interface for registering Valgrind mempools doesn't seem to make any reference to names. PostgreSQL's mempools have names embedded in their header blocks so it'd just be a matter of teaching Valgrind what byte-range was the pool name.

Am I missing something or is this just not possible right now?

A viable alternative might be program-callbacks to filter leak check reports or add annotation info to them. But again I don't see anything in Valgrind that suggests this is possible.

It seems like something others would've wanted, so maybe I'm just not seeing the way to do it.

Context: I suspect that somewhere an allocation should be in a cache, but it's being allocated in PostgreSQL's TopMemoryContext instead. So it's outliving the cache it should be destroyed as part of.

Upvotes: 5

Views: 163

Answers (0)

Related Questions