Re: How to instrument a custom allocator properly?

Tomas Vondra <[email protected]>
Newsgroups gmane.comp.debugging.valgrind
Message-ID <[email protected]>

On 8/6/19 11:47 AM, Ruurd Beerstra wrote:
> Hi,
> 
> We have a custom allocator which I have instrumented with VALGRIND 
> macro’s so we can run our software under valgrind and detect memory 
> abuse and leaks.
> 
> Works great, and has done so for many years now.
> 
> That allocator used to use sbrk() to get the raw memory in large chunks, 
> and then uses VALGRIND_MALLOCLIKE_BLOCK when it doled out smaller chunks 
> to the applications.
> 
> But sbrk() does not work well when a single application uses multiple 
> allocators, and our software now links with 3^rd party code which has 
> its own ideas about allocation.
> 
> That caused problems and instability.
> 
> So, our custom allocator now uses the system ‘malloc()’ instead of 
> sbrk() to allocate large chunks, which solves the interference problems 
> between allocators.
> That stabilized the software.
> 
> However, now valgrind gets confused: It sees overlapping mallocs() (the 
> smaller VALGRIND_MALLOCLIKE_BLOCKS are within the large chunks allocated 
> with malloc()).
> 
> I’m now struggling with the instrumentation in our allocator but I can’t 
> get it to work.
> 
> The error reports I get are just plain wrong: It says stuff like:
> 
> 2019-08-06 00:57:20: ==30298== Invalid read of size 1
> 
> 2019-08-06 00:57:20: ==30298==    at 0x4059CF: main (valgrindTest.c:126)
> 
> 2019-08-06 00:57:20: ==30298==  Address 0x5e43878 is 72 bytes inside a 
> block of size 65,536 alloc'd
> 
> 2019-08-06 00:57:20: ==30298==    at 0x4C29DDB: malloc 
> (vg_replace_malloc.c:299)
> 
> 2019-08-06 00:57:20: ==30298==    by 0x42DE98: mal_own_sbrk 
> (al_alloc.c:4251)
> 
> 2019-08-06 00:57:20: ==30298==    by 0x42E7E5: mal_inc_space 
> (al_alloc.c:4442)
> 
> 2019-08-06 00:57:20: ==30298==    by 0x4290E3: _mal_allocater 
> (al_alloc.c:1915)
> 
> 2019-08-06 00:57:20: ==30298==    by 0x428235: mal_allocater_c 
> (al_alloc.c:1608)
> 
> 2019-08-06 00:57:20: ==30298==    by 0x426C10: vmal_reserve_id 
> (al_alloc.c:1131)
> 
> 2019-08-06 00:57:20: ==30298==    by 0x42690B: mal_reserve_id 
> (al_alloc.c:999)
> 
> 2019-08-06 00:57:20: ==30298==    by 0x405495: main (valgrindTest.c:46)
> 
> So the offending byte is always in one of the “outer” malloced block of 
> 64KB, which is not what I want.
> The stack is that of the allocator itself, also not what I want (the 
> function is still called mal_own_sbrk, but that is  a misnomer now).
> 

I'm not sure what the problem is (I've seen these "invalid read" reports 
in various situations, e.g. when accessing "padding" space in a struct, 
or when accessing areas marked as VALGRIND_MAKE_MEM_NOACCESS).

But maybe take a look at this:

https://github.com/postgres/postgres/blob/master/src/backend/utils/mmgr/aset.c

That's a custom allocator used by PostgreSQL, using pretty much exactly 
the same design like you do (based on malloc etc.), and it's heavily 
valgrind-enabled. And it works quite fine. So maybe you could look at 
what we're doing there and copy the instrumentation ...

> Another example:
> 
> ==16897==  Uninitialised value was created by a stack allocation
> 
> ==16897==    at 0x492748: evt_get_3glLong_event (evt_fun.c:388)
> 
> ==16897==
> 
> The memory in question here is allocated using our allocator (and not on 
> the stack, so the reports is just wrong).
> Secondly, the rest of call stack is missing. Seems valgrind is confused 
> here.
> 

If I had to guess, I'd say this is complaining about the local variable 
not being initialized before use, not the memory allocated on heap.

regards
T.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.