A client creates an instance of heap; providing it with memory segments to manage. Subsequent operations can then be invoked to obtain memory from those registered segments.
It detects two types of leak by scanning the BSS and DATA segments and identifying any nodes referenced from there. Then each of these referenced nodes is scanned to look for further references.
The heap implements a "best fit" model, for allocation of dynamic memory. This means that free blocks are maintained in size order and hence the most appropriate one can be used to satisfy client requests. This minimises fragmentation of the dynamically allocated memory.
The free blocks are held in a binary tree (using bintree) which provide fast searching for the appropriate block.
#define LUB_HEAP_ZERO_ALLOC ((void*)-1) |
This 'magic' pointer is returned when a client requests zero bytes The client can see that the allocation has succeeded, but cannot use the "memory" returned. This pointer may be passed transparently back to lub_heap_realloc() without impact.
typedef void lub_heap_foreach_fn(void *block,unsigned index,size_t size,void *arg) |
This type defines a function prototype to be used to iterate around each of a number of things in the system.
typedef struct lub_heap_free_block_s lub_heap_free_block_t |
This type is used to reference an instance of a free block
typedef struct lub_heap_stats_s lub_heap_stats_t |
This type defines the statistics available for each heap.
typedef struct lub_heap_s lub_heap_t |
This type is used to reference an instance of a heap.
typedef struct _lub_partition_spec lub_partition_spec_t |
This type is used to specify any local_ requirements
typedef struct _lub_partition lub_partition_t |
This type is used to reference an instance of a heap.
enum lub_heap_align_t |
This type is used to indicate the alignment required for a memory allocation.
enum lub_heap_show_e |
This type defines how leak details should be displayed
enum lub_heap_status_t |
This type is used to indicate the result of a dynamic memory allocation
size_t lub_heap__get_max_free | ( | lub_heap_t * | instance | ) |
This method provides the size, in bytes, of the largest allocation which can be performed.
instance | The instance on which to operate |
void lub_heap__get_stats | ( | lub_heap_t * | instance, | |
lub_heap_stats_t * | stats | |||
) |
This operation fills out a statistics structure with the details for the specified heap.
instance | The instance on which to operate |
stats | A client provided structure to fill out with the heap details |
void lub_heap__set_framecount | ( | unsigned | framecount | ) |
framecount | The new framecount to use |
void lub_heap_add_segment | ( | lub_heap_t * | instance, | |
void * | start, | |||
size_t | size | |||
) |
This operation augments an existing heap with some more memory to manage. NB. if the memory happens to be follow on from the initial memory segment then the two will merge into a single larger segment. This means that a heap which is expanded with a sbrk() like mechanism will contain a single expandible segment.
instance | The heap instance on which to operate |
start | The beginning of the memory segment to be managed |
size | The number of bytes available for use in this segment |
lub_heap_status_t lub_heap_cache_init | ( | lub_heap_t * | instance, | |
lub_heap_align_t | max_block_size, | |||
size_t | num_max_blocks | |||
) |
This operation adds a cache to the current heap, which speeds up the allocation and releasing of smaller block sizes.
instance | The instance on which to operate |
max_block_size | The maximum block size for the cache |
num_max_blocks | The number of maximum sized blocks to make available. |
This operation controls runtime heap corruption detection. This means that during every heap operation a full check is done of the specified heap, before any allocations/free are performed. This has a performance overhead but provides a valuable aid in finding a memory corrupting client. Corruption will be spotted the first time a memory operation is performed AFTER it has occured.
By default checking is switched off.
enable | BOOL_TRUE to enable checking or BOOL_FALSE to disable |
bool_t lub_heap_check_memory | ( | lub_heap_t * | instance | ) |
This operation checks the integrety of the memory in the specified heap. Corruption will be spotted the first time a check is performed AFTER it has occured.
lub_heap_t* lub_heap_create | ( | void * | start, | |
size_t | size | |||
) |
This operation creates a dynamic heap from the provided memory segment.
start | The begining of the first memory segment to associate with this heap |
size | The number of bytes available for use in the first segment. |
void lub_heap_destroy | ( | lub_heap_t * | instance | ) |
This operation creates a dynamic heap from the provided memory segment.
instance | The heap instance on which to operate |
void lub_heap_foreach_free_block | ( | lub_heap_t * | instance, | |
lub_heap_foreach_fn * | fn, | |||
void * | arg | |||
) |
This operation is a diagnostic which can be used to iterate around all the free blocks in the specified heap. For example it may be desirable to output information about each of the free blocks present.
instance | The heap instance on which to operate |
fn | The client provided function to call for each free block |
arg | Some client specific data to pass through to the callback function. |
void lub_heap_foreach_segment | ( | lub_heap_t * | instance, | |
lub_heap_foreach_fn * | fn, | |||
void * | arg | |||
) |
This operation is a diagnostic which can be used to iterate around all the segments in the specified heap. For example it may be desirable to output information about each of the segments present.
instance | The heap instance on which to operate |
fn | The client provided function to call for each free block |
arg | Some client specific data to pass through to the callback function. |
void lub_heap_init | ( | const char * | program_name | ) |
This operation is used to initialise the heap management subsystem
program_name | The full pathname of the current executable This is typically obtained from argv[0] in main() |
bool_t lub_heap_is_checking | ( | void | ) |
This operation indicates the current status of the full memory checking facility.
bool_t lub_heap_is_tainting | ( | void | ) |
This operation indicates the current status of the memory tainting facility
bool_t lub_heap_leak_report | ( | lub_heap_show_e | how, | |
const char * | substring | |||
) |
This function dumps all the context details for the heap to stdout. 'how' is one of the following values: 0 - show only leaks 1 - show partial leaks (no references to the start of the block) 2 - show all allocations (VERY VERBOSE)
NB. if tainting is switched off then this function will not perform any memory scanning and will simply show all the allocated blocks.
how | how to display the details |
substring | an optional substring to use to filter contexts. Only contexts which contain the substring will be displayed |
void lub_heap_leak_restore_detection | ( | lub_heap_t * | instance | ) |
This operation signals the end of a section of code which should not have any of it's heap usage monitored by the leak detection code.
NB. you may nest the usage of lub_heap_leak_suppress_detection() and lub_heap_leak_restore_detection() in which case only when the outermost section has been terminated will monitoring commence again.
instance | The instance on which to operate |
void lub_heap_leak_scan | ( | void | ) |
This function scans memory to identify memory leaks
NB. if tainting is switched off then this function may miss some leaks as references may remain in freed memory.
void lub_heap_leak_suppress_detection | ( | lub_heap_t * | instance | ) |
This operation signals the start of a section of code which should not have any of it's heap usage monitored by the leak detection code.
instance | The instance on which to operate |
size_t lub_heap_overhead_size | ( | lub_heap_align_t | max_block_size, | |
size_t | num_max_blocks | |||
) |
This operation returns the overhead, in bytes, which is required to implement a heap instance. This provide clients the means of calculating how much memory they need to assign for a heap instance to manage.
max_block_size | The maximum block size for the cache |
num_max_blocks | The number of maximum sized blocks to make available. |
lub_heap_status_t lub_heap_realloc | ( | lub_heap_t * | instance, | |
char ** | ptr, | |||
size_t | size, | |||
lub_heap_align_t | alignment | |||
) |
This operation changes the size of the object referenced by a passed in pointer to "size". The contents will be unchanged up to the minimum of the old and new sizes. If the new size is larger, the new space is uninitialised.
instance | The heap instance on which to operate |
ptr | Reference to a pointer containing previously allocated memory or NULL. |
size | The number of bytes required for the object |
alignment | The alignement required for a new allocations. |
void lub_heap_show | ( | lub_heap_t * | instance, | |
bool_t | verbose | |||
) |
This operation dumps the salient details of the specified heap to stdout
instance | The instance on which to operate |
verbose | Whether to be verbose or not |
void* lub_heap_static_alloc | ( | lub_heap_t * | instance, | |
size_t | size | |||
) |
This operation allocates some "static" memory from a heap. This is memory which will remain allocted for the lifetime of the heap instance. "static" memory allocation has zero overhead and causes zero fragmentation.
NB. static allocation are only handed out from the first memory segment
instance | The heap instance on which to operate |
size | The number of bytes to allocate |
void lub_heap_stop_here | ( | lub_heap_status_t | status, | |
char * | old_ptr, | |||
size_t | new_size | |||
) |
This function is invoked whenever a call to lub_heap_realloc() fails. It is provided as a debugging aid; simple set a breakpoint to stop execution of the program and any failures will be caught in context.
status | The failure status of the the call to realloc |
old_ptr | The old value of the pointer passed in |
new_size | The requested number of bytes |
This operation controls the tainted memory facility. This means that during certain heap operations memory can be filled with some well defined bit patterns. This causes a slight performance overhead but can be used to shake out bugs such and free-memory-reads and uninitialised-memory-reads
By default tainting is switched off.
enable | BOOL_TRUE to enable tainting or BOOL_FALSE to disable |
bool_t lub_partition_check_memory | ( | lub_partition_t * | instance | ) |
This operation checks the integrety of the memory in the specified partition. Corruption will be spotted the first time a check is performed AFTER it has occured.
lub_partition_t* lub_partition_create | ( | const lub_partition_spec_t * | spec | ) |
This operation creates a partition
spec | This is used to specify the details to be used for the partition. |
void lub_partition_kill | ( | lub_partition_t * | instance | ) |
This operation starts the process of killing a partition.
instance | The heap instance on which to operate |
lub_heap_status_t lub_partition_realloc | ( | lub_partition_t * | instance, | |
char ** | ptr, | |||
size_t | size, | |||
lub_heap_align_t | alignment | |||
) |
This operation changes the size of the object referenced by a passed in pointer to "size". The contents will be unchanged up to the minimum of the old and new sizes. If the new size is larger, the new space is uninitialised.
instance | The partition instance on which to operate |
ptr | Reference to a pointer containing previously allocated memory or NULL. |
size | The number of bytes required for the object |
alignment | The alignment required for a new allocations. |
void lub_partition_show | ( | lub_partition_t * | instance, | |
bool_t | verbose | |||
) |
This operation dumps the salient details of the specified partition to stdout
instance | The instance on which to operate |
verbose | Whether to be verbose or not |
void lub_partition_stop_here | ( | lub_heap_status_t | status, | |
char * | old_ptr, | |||
size_t | new_size | |||
) |
This function is invoked whenever a call to lub_partition_realloc() fails. It is provided as a debugging aid; simple set a breakpoint to stop execution of the program and any failures will be caught in context.
status | The failure status of the the call to realloc |
old_ptr | The old value of the pointer passed in |
new_size | The requested number of bytes |