gstreamer/ext/tarkin/mem.c

154 lines
2.9 KiB
C
Raw Normal View History

/*
* Debugging implementation of MALLOC and friends
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#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