|
From: Jeremy F. <je...@go...> - 2005-02-28 21:18:41
|
The memcheck VALGRIND_MAKE_(READABLE|WRITABLE|NOACCESS) client calls
primarily change the V/A-bit state for a range of memory. As a side
effect, they also create an ID value which is returned, which identifies
that range of memory (a "general block").
I submit that these general blocks are not very useful, and even if they
are useful, they shouldn't be created by the MAKE_* requests.
The problem with general blocks are:
1. They are completely disassociated with the rest of the memory
management system. For example, if you create one inside a
malloced block, and then free that memory, the general block will
stay around, even if that memory later gets recycled.
2. They're not consistent with themselves. There's no attempt to
define what happens if they overlap; you can have multiple general
blocks at the same address and size.
3. Unless you remember the IDs and remember to remove them manually,
they keep building up, forming a perminent memory leak within
Valgrind.
4. (The implementation is pretty inefficient, using linear array
search for all operations. This is easy to fix.)
I generally use these requests to touch up the V/A bits on a piece of
memory, ignoring the return value. Until I actually looked at how they
worked, I didn't realize they actually create a piece of long-standing
state; I have quite a bit of code which will eventually explode under
the weight of general blocks.
Is anyone actually using the ID value returned by the MAKE_* requests?
Do we need general blocks at all? Can I remove them? If they are
useful, there should be a separate call, VALGRIND_CREATE_BLOCK(addr,
len, type?), to create them (with some better-defined semantics with
respect to each other and the heap management machinery).
(Note that these are distinct from the CustomAlloc heap chunks made by
VALGRIND_MALLOCLIKE/FREELIKE, which have their own problems.)
J
|