|
From: Marc M. <5.m...@gm...> - 2018-02-27 09:30:42
|
Hi I am working on a custom memory allocator, and I'm currently trying to integrate Valgrind with it, so that we can use memcheck with it. I think I have understood properly the documentation, and I have a correct implementation. But there is still one issue remaining. In our memory allocator, memory chunks can be allocated in one pool and freed in another (different) pool. This is no problem, because chunks have a specific size, and they are pushed to a queue of free chunks. This, when integrated with Valgrind, causes that the pools specified when calling VALGRIND_MEMPOOL_ALLOC and VALGRIND_MEMPOOL_FREE are not the same. This does not give any error nor warning (maybe it should?). Later, the chunk is reused in the new pool, and when Valgrind checks for overlaps, it outputs this: Block 0x6f17a00..0x6f17bff overlaps with block 0x6f17a00..0x6f17bff Which makes complete sense: the same chunk has been used in two pools (although never "at the same time"). The chunks come with no information to the allocator, so there is no easy way of checking which was the original pool. If this was the case, I could just do a FREE from the original pool. Is there any other way to tell Valgrind that one chunk has swapped pools? (If something seems wrong with my logic, tell me, because I may have misundertood the documentation. I'm writing this because the output of Valgrind fits with what I think it's happening). Thanks Marc |
|
From: John R. <jr...@bi...> - 2018-02-27 14:49:57
|
On 02/27/2018 09:30 UTC, Marc Marí wrote: > In our memory allocator, memory chunks can be allocated in one pool and > freed in another (different) pool. This is no problem, because chunks > have a specific size, and they are pushed to a queue of free chunks. Well, yes it is a problem ... because memcheck does not understand. Such an implementation violates the property that a block belongs to one specific and unchanging pool. It is likely that the soonest-to-implement solution is for the custom allocator to free() a block back into the same pool from which it was allocated. On a 32-bit architecture this should be easy: the entire address space is only 1M pages of 4KB, and 1M of bits is only 128KB. Give each pool such a bitmap which implements the characteristic function "do I manage this page?" For a 64-bit architecture, in practice a small handful of 4GiB regions will cover all the pools. So divide-and-conquer. |