I'm trying to use kmemleak to make sure that my software doesn't have any memory leaks, but I've encountered a problem with the tool reporting a lot of false positives. The issue is that my application doesn't allocate/free memory explicitly but is using memory pools instead. The thing that confuses kmemleak is that the allocator (by the allocator I mean an object that is responsible for managing memory pools) doesn't return a pointer to the allocated memory but rather to one of its member. The point of not returning the whole allocated object is that each element allocated from the mempool has associated a few bytes of metadata and I don't want the memory consumer to be aware of this additional bytes. When freeing an element, the allocator is able to recover the address of the originally allocated memory easily by using container_of() macro. It works like this:
struct element {
uint8_t allocator_metadata_1;
uint16_t allocator_metadata_2;
char[] data;
}
void *allocate_element(void *mempool) {
struct element *new_elem;
new_elem = get_free_element_from_mempool(mempool);
return new_elem->data;
}
void free_element(void *mempool, void *element_to_remove) {
struct element *elem;
elem = container_of(element_to_remove, struct element, data);
return_element_to_mempool(mempool, elem);
}
To keep the example as simple as possible let's assume get_free_element_from_mempool() return_element_to_mempool() are functions that manage retrieving/returning memory from/to mempool and operates on allocator_metadata_1 and allocator_metadata_2 fields.
So as you can see there are a few bytes of memory that are not pointed by anyone while element is in use, but thanks to container_of() macro it doesn't mean that this memory is lost.
My question is whether it is possible to let kmemleak know that it should track these elements from memory pool in a different manner than a regular memory allocations?
Turns out that it is possible for kmemleak to work with custom memory pools. The thing I had to do was calling
kmemleak_free()on eachstruct elementwhich was allocated during setting up memory pool (I mean the moment when memory pool is populated with empty elements). That way kmemleak wasn't tracking this memory anymore. Then I extendedallocate_element()andfree_element()in the following manner: