mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 14:26:43 +00:00
144 lines
3 KiB
C
144 lines
3 KiB
C
|
/*
|
||
|
* Debugging implementation of MALLOC and friends
|
||
|
*/
|
||
|
|
||
|
|
||
|
#include "mem.h"
|
||
|
|
||
|
#if defined(DBG_MEMLEAKS)
|
||
|
|
||
|
typedef struct {
|
||
|
void *mem;
|
||
|
char *allocated_in_func;
|
||
|
char *allocated_in_file;
|
||
|
unsigned int allocated_in_line;
|
||
|
} MemDesc;
|
||
|
|
||
|
|
||
|
static int initialized = 0;
|
||
|
static int alloc_count = 0;
|
||
|
static MemDesc *alloc_list = NULL;
|
||
|
|
||
|
|
||
|
static
|
||
|
void dbg_memleaks_done (int exitcode, void *dummy)
|
||
|
{
|
||
|
unsigned int i;
|
||
|
(void) dummy;
|
||
|
|
||
|
if (exitcode == 0 && alloc_count != 0) {
|
||
|
fprintf (stderr, "\nmemory leak detected !!!\n");
|
||
|
fprintf (stderr, "\nalloc_count == %i\n\n", alloc_count);
|
||
|
for (i=0; i<alloc_count; i++) {
|
||
|
MemDesc *d = &alloc_list[i];
|
||
|
fprintf (stderr, "chunk %p allocated in %s (%s: %u) not free'd !!\n",
|
||
|
d->mem, d->allocated_in_func, d->allocated_in_file,
|
||
|
d->allocated_in_line);
|
||
|
}
|
||
|
free(alloc_list);
|
||
|
}
|
||
|
fprintf (stderr, "\n");
|
||
|
}
|
||
|
|
||
|
|
||
|
static
|
||
|
void dbg_memleaks_init (void)
|
||
|
{
|
||
|
on_exit (dbg_memleaks_done, NULL);
|
||
|
initialized = 1;
|
||
|
}
|
||
|
|
||
|
|
||
|
void* dbg_malloc (char* file, int line, char *func, size_t bytes)
|
||
|
{
|
||
|
void *mem = (void*) malloc (bytes);
|
||
|
MemDesc *d;
|
||
|
|
||
|
if (!initialized)
|
||
|
dbg_memleaks_init();
|
||
|
|
||
|
alloc_count++;
|
||
|
alloc_list = realloc (alloc_list, alloc_count * sizeof(MemDesc));
|
||
|
|
||
|
d = &alloc_list[alloc_count-1];
|
||
|
d->mem = mem;
|
||
|
d->allocated_in_func = func;
|
||
|
d->allocated_in_file = file;
|
||
|
d->allocated_in_line = line;
|
||
|
|
||
|
return mem;
|
||
|
}
|
||
|
|
||
|
|
||
|
void* dbg_calloc (char* file, int line, char *func, size_t count, size_t bytes)
|
||
|
{
|
||
|
void *mem = (void*) calloc (count, bytes);
|
||
|
MemDesc *d;
|
||
|
|
||
|
if (!initialized)
|
||
|
dbg_memleaks_init();
|
||
|
|
||
|
alloc_count++;
|
||
|
alloc_list = realloc (alloc_list, alloc_count * sizeof(MemDesc));
|
||
|
|
||
|
d = &alloc_list[alloc_count-1];
|
||
|
d->mem = mem;
|
||
|
d->allocated_in_func = func;
|
||
|
d->allocated_in_file = file;
|
||
|
d->allocated_in_line = line;
|
||
|
|
||
|
return mem;
|
||
|
}
|
||
|
|
||
|
|
||
|
void* dbg_realloc (char *file, int line, char *func, char *what,
|
||
|
void *mem, size_t bytes)
|
||
|
{
|
||
|
unsigned int i;
|
||
|
|
||
|
for (i=0; i<alloc_count; i++) {
|
||
|
if (alloc_list[i].mem == mem) {
|
||
|
alloc_list[i].mem = (void*) realloc (mem, bytes);
|
||
|
return alloc_list[i].mem;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (mem != NULL) {
|
||
|
fprintf (stderr,
|
||
|
"%s: trying to reallocate unknown chunk %p (%s)\n"
|
||
|
" in %s (%s: %u) !!!\n",
|
||
|
__FUNCTION__, mem, what, func, file, line);
|
||
|
exit (-1);
|
||
|
}
|
||
|
|
||
|
return dbg_malloc(file, line, func, bytes);
|
||
|
}
|
||
|
|
||
|
|
||
|
void dbg_free (char *file, int line, char *func, char *what, void *mem)
|
||
|
{
|
||
|
unsigned int i;
|
||
|
|
||
|
if (!initialized)
|
||
|
dbg_memleaks_init();
|
||
|
|
||
|
for (i=0; i<alloc_count; i++) {
|
||
|
if (alloc_list[i].mem == mem) {
|
||
|
free (mem);
|
||
|
alloc_count--;
|
||
|
memmove (&alloc_list[i], &alloc_list[i+1],
|
||
|
(alloc_count - i) * sizeof(MemDesc));
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fprintf (stderr, "%s: trying to free unknown chunk %p (%s)\n"
|
||
|
" in %s (%s: %u) !!!\n",
|
||
|
__FUNCTION__, mem, what, func, file, line);
|
||
|
exit (-1);
|
||
|
}
|
||
|
|
||
|
|
||
|
#endif
|
||
|
|