You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
spOSMroute/base/memoryleak.c

214 lines
4.9 KiB

/*
* memoryleak.c
* Copyright (C) Steffen Pohle 2009 <steffen@gulpe.de>
*
* main.c is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* main.c is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "memoryleak.h"
#include "system.h"
#define MEMORY_DUMPINFO 1000
struct memoryleak_data memory[MEMORYLEAK_MAX];
int memory_used = 0;
int memory_size = 0;
int memory_blocknext = 0;
struct memoryleak_data *ml_findfree ();
struct memoryleak_data *ml_find (void *ptr);
/************************************************************************/
struct memoryleak_data *ml_findfree () {
int i;
for (i = 0; i < MEMORYLEAK_MAX; i++)
if (memory[i].ptr == NULL) return &memory[i];
return NULL;
};
struct memoryleak_data *ml_find (void *ptr) {
int i;
for (i = 0; i < MEMORYLEAK_MAX; i++)
if (memory[i].ptr == ptr) return &memory[i];
return NULL;
};
void *ml_calloc(size_t nmemb, size_t size) {
void *ptr;
ptr = calloc(nmemb, size);
d_printf ("memoryleak: function not yet fully implemented.");
errorexit (-2);
return ptr;
};
void *ml_malloc(size_t size) {
struct memoryleak_data *md = ml_findfree ();
int i, j;
void *buffer[ML_BT_SIZE];
char **strings;
if (md == NULL) {
d_printf ("memoryleak malloc MEMORYLEAK_MAX reached\n");
for (j = 0; j < MEMORYLEAK_MAX; j++) {
d_printf ("memoryleak : (%6d) size:%d ptr:%p text:%s", j, memory[j].size, memory[j].ptr, memory[j].text);
for (i = 1; i < memory[j].btcnt; i++) if (memory[j].ptr) // don't show ml_malloc call.
d_printf (" frame:%3d %s", i, memory[j].btstr[i]);
}
errorexit (-1);
}
if (memory_size+size > MEMORYLEAK_MAXMEM) {
d_printf ("ml_malloc: too much memory (%lu+%lu) %lu", memory_size, size, MEMORYLEAK_MAXMEM);
errorexit (-1);
}
md->ptr = malloc (size);
md->size = size;
#if !defined(__MINGW32CE__) && !defined(_WIN32_WCE) && !defined(__MINGW32__) && !defined(ANDROID)
md->btcnt = backtrace(buffer, ML_BT_SIZE);
/* if someone finds out how this should really work please let me know? */
strings = (char **) backtrace_symbols(buffer, md->btcnt);
if (strings == NULL) {
d_printf ("backtrace_symbols: %s", strerror(errno));
exit(EXIT_FAILURE);
}
#else
md->btcnt = 0;
strings = NULL;
#endif
for (i = 0; (i < md->btcnt) && (i < ML_BT_SIZE); i++) {
snprintf (md->btstr[i], ML_BT_TEXT, "%p:%s", buffer[i], strings[i]);
}
free(strings);
md->text[0] = 0;
memory_used ++;
memory_size += size;
return md->ptr;
};
void ml_free(void *ptr) {
struct memoryleak_data *md = ml_find (ptr);
if (ptr == NULL) return;
if (md == NULL) {
d_printf ("memoryleak free NULL! allocated without unsing ml_ function?\n");
errorexit (-1);
}
memory_used--;
memory_size -= md->size;
free (md->ptr);
md->ptr = NULL;
md->text[0] = 0;
md->size = 0;
};
void *ml_realloc(void *ptr, size_t size) {
struct memoryleak_data *md = ml_find (ptr);
void *test = NULL;
if (ptr == NULL) md = ml_findfree ();
if (md == NULL) {
d_printf ("memoryleak realloc NULL\n");
errorexit (-1);
}
memory_size = memory_size - md->size + size;
if (memory_size > MEMORYLEAK_MAXMEM) {
d_printf ("ml_realloc: too much memory %lld > %lld", memory_size, MEMORYLEAK_MAXMEM);
errorexit (-1);
}
test = realloc (ptr, size);
if (test == NULL && size > 0) {
d_printf ("%s:%d (%s) test == NULL", __FILE__, __LINE__, __FUNCTION__);
errorexit (-1);
}
md->ptr = test;
md->size = size;
return md->ptr;
};
void ml_addinfo (void *ptr, char *text) {
struct memoryleak_data *md = ml_find (ptr);
if (md) {
strncpy (md->text, text, ML_BT_TEXT);
}
};
void ml_get_stats (struct memoryleak_info *m) {
m->blocks = memory_used;
m->size = memory_size;
// if (memory_used > memory_blocknext) {
// ml_debug ();
// while (memory_used > memory_blocknext) memory_blocknext += MEMORY_DUMPINFO;
// }
};
void ml_init () {
int i;
for (i = 0; i < MEMORYLEAK_MAX; i++) {
memory[i].size = 0;
memory[i].ptr = NULL;
}
};
void ml_debug () {
int i, j;
void *ptr1, *ptr2;
ptr1 = (void*)&i;
ptr2 = ptr1+1;
d_printf ("*** memoryleak debug: %p, %p", ptr1, ptr2);
d_printf ("size void:%d char:%d", sizeof (void), sizeof (char));
for (j = 0; j < MEMORYLEAK_MAX; j++) if (memory[j].ptr) {
d_printf (" memory(%6d) size:%d ptr:%p text:%s", j, memory[j].size, memory[j].ptr, memory[j].text);
for (i = 1; i < memory[j].btcnt; i++) if (memory[j].ptr) // don't show ml_malloc call.
d_printf (" frame:%3d %s", i, memory[j].btstr[i]);
}
};