Remove obsolete memory debugging feature.

SVN revision: 13714
This commit is contained in:
Kim Woelders 2005-03-12 15:27:31 +00:00
parent 8d17294eb9
commit aeab6a9554
3 changed files with 26 additions and 462 deletions

82
src/E.h
View File

@ -1919,7 +1919,31 @@ const char *EGetSavePrefix(void);
const char *EGetSavePrefixCommon(void);
/* memory.c */
void EDisplayMemUse(void);
#define Ecalloc calloc
#define Emalloc malloc
#define Efree free
#define Erealloc realloc
#define _EFREE(p) do { if (p) { Efree(p); p = NULL; } } while (0)
#define _EFDUP(p, s) do { if (p) Efree(p); p = Estrdup(s); } while (0)
#if USE_LIBC_STRDUP
#define Estrdup(s) ((s) ? strdup(s) : NULL)
#else
char *Estrdup(const char *s);
#endif
#if USE_LIBC_STRNDUP
#define Estrndup(s,n) ((s) ? strndup(s,n) : NULL)
#else
char *Estrndup(const char *s, int n);
#endif
#if USE_LIBC_SETENV
#define Esetenv setenv
#else
int Esetenv(const char *name, const char *value, int overwrite);
#endif
char *Estrdupcat2(char *ss, const char *s1, const char *s2);
char **EstrlistDup(char **lst, int num);
void EstrlistFree(char **lst, int num);
char *EstrlistJoin(char **lst, int num);
@ -2263,62 +2287,6 @@ char CanZoom(void);
void ZoomInit(void);
void Zoom(EWin * ewin);
#if USE_LIBC_MALLOC
#define Ecalloc calloc
#define Emalloc malloc
#define Efree free
#define Erealloc realloc
#elif defined(__FILE__) && defined(__LINE__)
#define Ecalloc(n, x) \
__Ecalloc(n, x, __FILE__, __LINE__)
#define Emalloc(x) \
__Emalloc(x, __FILE__, __LINE__)
#define Efree(x) \
__Efree(x, __FILE__, __LINE__)
#define Erealloc(x, y) \
__Erealloc(x, y, __FILE__, __LINE__)
void *__Ecalloc(int nmemb, int size, const char *file, int line);
void *__Emalloc(int size, const char *file, int line);
void __Efree(void *ptr, const char *file, int line);
void *__Erealloc(void *ptr, int size, const char *file, int line);
#else
/* We still want our special handling, even if they don't have file/line stuff -- mej */
#define Ecalloc(n, x) \
__Ecalloc(n, x, "<unknown>", 0)
#define Emalloc(x) \
__Emalloc(x, "<unknown>", 0)
#define Efree(x) \
__Efree(x, "<unknown>", 0)
#define Erealloc(x, y) \
__Erealloc(x, y, "<unknown>", 0)
#endif
#define _EFREE(p) do { if (p) { Efree(p); p = NULL; } } while (0)
#define _EFDUP(p, s) do { if (p) Efree(p); p = Estrdup(s); } while (0)
#if USE_LIBC_STRDUP
#define Estrdup(s) ((s) ? strdup(s) : NULL)
#else
char *Estrdup(const char *s);
#endif
#if USE_LIBC_STRNDUP
#define Estrndup(s,n) ((s) ? strndup(s,n) : NULL)
#else
char *Estrndup(const char *s, int n);
#endif
#if USE_LIBC_SETENV
#define Esetenv setenv
#else
int Esetenv(const char *name, const char *value, int overwrite);
#endif
char *Estrdupcat2(char *ss, const char *s1, const char *s2);
/*
* Global vars
*/

View File

@ -828,14 +828,6 @@ IPC_Version(const char *params __UNUSED__, Client * c __UNUSED__)
e_wm_version, e_wm_date);
}
#if !USE_LIBC_MALLOC
static void
IPC_MemDebug(const char *params __UNUSED__, Client * c __UNUSED__)
{
EDisplayMemUse();
}
#endif
static void
IPC_Hints(const char *params, Client * c __UNUSED__)
{
@ -1443,19 +1435,6 @@ IpcItem IPCArray[] = {
"use \"dialog_ok <message>\" to pop up a dialog box\n"},
{
IPC_Border, "border", NULL, "List available borders\n", NULL},
#if !USE_LIBC_MALLOC
{
IPC_MemDebug,
"dump_mem_debug", NULL,
"Dumps memory debugging information out to e.mem.out",
"Use this command to have E dump its current memory debugging table\n"
"to the e.mem.out file. NOTE: please read comments at the top of\n"
"memory.c to see how to enable this. This will let you hunt memory\n"
"leaks, over-allocations of memory, and other " "memory-related problems\n"
"very easily with all pointers allocated stamped with a time, call\n"
"tree that led to that allocation, file and line, "
"and the chunk size.\n"},
#endif
{
IPC_Screen, "screen", NULL, "Return screen information\n", NULL},
{

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2000-2004 Carsten Haitzler, Geoff Harrison and various contributors
* Copyright (C) 2005 Kim Woelders
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@ -21,390 +22,6 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "E.h"
#include <time.h>
#if !USE_LIBC_MALLOC
/* Define DBUG_MEM to 1 to get rudamentary pointer checking */
/* Define MEM_OUT to 1 to get full debug output. to make this work you have to */
/* put a file in the directory (cwd) you run E from calle e.sym */
/* to generate the e.sym file do: */
/* */
/* nm enlightenment | grep " T " > e.sym */
/* nm enlightenment | grep " t " > e.sym2 */
/* cat e.sym >> e.sym2 */
/* sort < e.sym2 > e.sym */
/* rm e.sym2 */
/* */
/* do that whenever you recompile enlightenment and place the e.sym file in */
/* the current working directory of enlightenment */
#define DBUG_MEM 0
#define MEM_OUT 0
#if DBUG_MEM
#define POINTERS_SIZE 50000
static unsigned int num_pointers = 0;
static void *pointers_ptr[POINTERS_SIZE];
static unsigned int pointers_size[POINTERS_SIZE];
#if MEM_OUT
static void *pointers_stack[POINTERS_SIZE][32];
static char pointers_file[POINTERS_SIZE][16];
static int pointers_line[POINTERS_SIZE];
static time_t pointers_time[POINTERS_SIZE];
#define PSTK(y, x) if (__builtin_frame_address(x)) \
pointers_stack[y][x] = __builtin_return_address(x);\
else goto end;
#define PST(y)\
{\
int _pi;\
for (_pi = 0; _pi < 32; _pi++)\
pointers_stack[y][_pi] = NULL;\
PSTK(y, 0); PSTK(y, 1); PSTK(y, 2); PSTK(y, 3); PSTK(y, 4);\
PSTK(y, 5); PSTK(y, 6); PSTK(y, 7); PSTK(y, 8); PSTK(y, 9);\
PSTK(y, 10); PSTK(y, 11); PSTK(y, 12); PSTK(y, 13); PSTK(y, 14);\
PSTK(y, 15); PSTK(y, 16); PSTK(y, 17); PSTK(y, 18); PSTK(y, 19);\
PSTK(y, 20); PSTK(y, 21); PSTK(y, 22); PSTK(y, 23); PSTK(y, 24);\
PSTK(y, 25); PSTK(y, 26); PSTK(y, 27); PSTK(y, 28); PSTK(y, 29);\
PSTK(y, 30); PSTK(y, 31);\
end:; \
}
static struct _symtab
{
void *val;
char *symbol;
}
*sym = NULL;
static int sym_count = 0;
static const char *
getsym(void *p)
{
int i;
for (i = 0; i < sym_count - 1; i++)
{
if ((p > sym[i].val) && (p < sym[i + 1].val))
return sym[i].symbol;
}
return "";
}
#endif
#endif
void
EDisplayMemUse()
{
#if DBUG_MEM
FILE *f;
unsigned int i, min, max, sum;
max = 0;
min = 0x7ffffff;
sum = 0;
if (!sym)
{
f = fopen("e.sym", "r");
if (f)
{
void *p;
char buf[256];
while (fscanf(f, "%p %*s %250s\n", &p, buf) != EOF)
{
sym_count++;
sym = realloc(sym, sizeof(struct _symtab) * sym_count);
sym[sym_count - 1].val = p;
sym[sym_count - 1].symbol = strdup(buf);
}
fclose(f);
}
}
f = fopen("e.mem.out", "w");
for (i = 0; i < num_pointers; i++)
{
char tm[32];
struct tm tim;
struct tm *tim2;
time_t t2;
sum += pointers_size[i];
if (pointers_size[i] < min)
min = pointers_size[i];
if (pointers_size[i] > max)
max = pointers_size[i];
t2 = pointers_time[i];
tim2 = localtime(&t2);
if (tim2)
{
memcpy(&tim, tim2, sizeof(struct tm));
strftime(tm, 31, "%T", &tim);
}
fprintf(f,
"%6i > %p %5i @ %s - %16s line %5i : "
"%s %s %s %s %s %s %s %s " "%s %s %s %s %s %s %s %s "
"%s %s %s %s %s %s %s %s " "%s %s %s %s %s %s %s %s\n", i,
pointers_ptr[i], pointers_size[i], tm, pointers_file[i],
pointers_line[i], getsym(pointers_stack[i][0]),
getsym(pointers_stack[i][1]), getsym(pointers_stack[i][2]),
getsym(pointers_stack[i][3]), getsym(pointers_stack[i][4]),
getsym(pointers_stack[i][5]), getsym(pointers_stack[i][6]),
getsym(pointers_stack[i][7]), getsym(pointers_stack[i][8]),
getsym(pointers_stack[i][9]), getsym(pointers_stack[i][10]),
getsym(pointers_stack[i][11]), getsym(pointers_stack[i][12]),
getsym(pointers_stack[i][13]), getsym(pointers_stack[i][14]),
getsym(pointers_stack[i][15]), getsym(pointers_stack[i][16]),
getsym(pointers_stack[i][17]), getsym(pointers_stack[i][18]),
getsym(pointers_stack[i][19]), getsym(pointers_stack[i][20]),
getsym(pointers_stack[i][21]), getsym(pointers_stack[i][22]),
getsym(pointers_stack[i][23]), getsym(pointers_stack[i][24]),
getsym(pointers_stack[i][25]), getsym(pointers_stack[i][26]),
getsym(pointers_stack[i][27]), getsym(pointers_stack[i][28]),
getsym(pointers_stack[i][29]), getsym(pointers_stack[i][30]),
getsym(pointers_stack[i][31]));
}
if (num_pointers > 0)
{
fprintf(f, "Num:%6i Sum:%8i Av:%8i Min:%8i Max%6i\n", num_pointers, sum,
sum / num_pointers, min, max);
}
fclose(f);
#endif
}
#if defined(__FILE__) && defined(__LINE__)
void *
__Ecalloc(int nmemb, int size, const char *file, int line)
{
void *p;
if (nmemb <= 0)
return NULL;
p = __Emalloc(nmemb * size, file, line);
if (!p)
return NULL;
memset(p, 0, nmemb * size);
return p;
}
void *
__Emalloc(int size, const char *file, int line)
{
void *p;
if (size <= 0)
return NULL;
p = malloc(size);
if (!p)
{
if (disp)
ecore_x_ungrab();
AlertX(_("Cannot allocate enough memory"), _("Ignore this"),
_("Restart Enlightenment"), _("Quit Enlightenment"),
_("WARNING!!!!!!\n" "\n"
"Allocation for %i bytes (%3.0f kB or %3.1f MB) did not succeed.\n"
"\n"
"Either this is a bug where ridiculous amounts of memory\n"
"are being allocated, or your system has run out of both\n"
"real and virtual memory and is unable to satisfy the request.\n"
"\n"
"If you have a low memory system it is suggested to either\n"
"purchase more memory, increase SWAP space, or reconfigure\n"
"Enlightenment to use less resources by turning features off.\n"
"\n" "The malloc requested was at %s, line %d\n "), size,
(float)size / 1024, (float)size / (1024 * 1024), file, line);
}
#if DBUG_MEM
if (p)
{
num_pointers++;
pointers_ptr[num_pointers - 1] = p;
pointers_size[num_pointers - 1] = size;
#if MEM_OUT
strcpy(pointers_file[num_pointers - 1], file);
pointers_line[num_pointers - 1] = line;
pointers_time[num_pointers - 1] = time(NULL);
PST(num_pointers - 1);
#endif
}
#endif
return p;
}
void *
__Erealloc(void *ptr, int size, const char *file, int line)
{
void *p;
#if DBUG_MEM
char bad = 0;
#endif
if (ptr == NULL)
{
if (size > 0)
return __Emalloc(size, file, line);
else
return NULL;
}
/* If we get here, we know ptr != NULL, so don't test for that case -- mej */
if (size <= 0)
{
__Efree(ptr, file, line);
return NULL;
}
#if DBUG_MEM
if (ptr)
{
unsigned int i;
bad = 1;
for (i = 0; i < num_pointers; i++)
{
if (pointers_ptr[i] == ptr)
{
bad = 0;
i = num_pointers;
}
}
}
if (bad)
{
if (disp)
ecore_x_ungrab();
AlertX(_("Error in reallocating memory that hasn't been allocated"),
_("Ignore this"), _("Restart Enlightenment"),
_("Quit Enlightenment"),
_("WARNING!!!!!!\n" "\n"
"Re-allocation for %i bytes (%3.0f kB or %3.1f MB)\n"
"for pointer %x is attempting to re-allocate memory for a\n"
"memory chunk that has not been allocated or has already been\n"
"freed.\n" "\n" "This is definitely a bug. Please report it.\n"
"\n" "The error occurred at %s, line %d.\n"), size,
(float)size / 1024, (float)size / (1024 * 1024), ptr, file,
line);
return NULL;
}
#endif
p = realloc(ptr, size);
if ((!p) && (size != 0))
{
if (disp)
ecore_x_ungrab();
AlertX(_("Cannot allocate enough memory"), _("Ignore this"),
_("Restart Enlightenment"), _("Quit Enlightenment"),
_("WARNING!!!!!!\n" "\n"
"Re-allocation for %i bytes (%3.0f kB or %3.1f MB) did not succeed.\n"
"\n"
"Either this is a bug where ridiculous amounts of memory\n"
"are being allocated, or your system has run out of both\n"
"real and virtual memory and is unable to satisfy the request.\n"
"\n"
"If you have a low memory system it is suggested to either\n"
"purchase more memory, increase SWAP space, or reconfigure\n"
"Enlightenment to use less resources by turning features off.\n"
"\n" "The realloc requested was at %s, line %d\n "), size,
(float)size / 1024, (float)size / (1024 * 1024), file, line);
}
#if DBUG_MEM
if (p)
{
unsigned int i;
bad = 1;
for (i = 0; i < num_pointers; i++)
{
if (pointers_ptr[i] == ptr)
{
pointers_size[i] = size;
pointers_ptr[i] = p;
i = num_pointers;
}
}
}
#endif
return p;
}
void
__Efree(void *ptr, const char *file, int line)
{
#if DBUG_MEM
char bad = 0;
#endif
#if DBUG_MEM
{
unsigned int i, j, k;
bad = 1;
for (i = 0; i < num_pointers; i++)
{
if (pointers_ptr[i] == ptr)
{
for (j = i; j < num_pointers - 1; j++)
{
pointers_ptr[j] = pointers_ptr[j + 1];
pointers_size[j] = pointers_size[j + 1];
#if MEM_OUT
for (k = 0; k < 32; k++)
pointers_stack[j][k] = pointers_stack[j + 1][k];
strcpy(pointers_file[j], pointers_file[j + 1]);
pointers_line[j] = pointers_line[j + 1];
pointers_time[j] = pointers_time[j + 1];
#endif
}
bad = 0;
i = num_pointers;
num_pointers--;
break;
}
}
}
if (bad)
{
if (disp)
ecore_x_ungrab();
AlertX(_("Error in freeing memory that hasn't been allocated"),
_("Ignore this"), _("Restart Enlightenment"),
_("Quit Enlightenment"),
_("WARNING!!!!!!\n" "\n"
"freeing for pointer %x is attempting to free memory for a\n"
"memory chunk that has not been allocated, or has already been\n"
"freed.\n" "\n" "This is definitely a bug. Please report it.\n"
"\n" "The error occurred at %s, line %d.\n"), ptr, file, line);
return;
}
#endif
if (!ptr)
{
if (disp)
ecore_x_ungrab();
AlertX(_("Error in attempting to free NULL pointer"),
_("Ignore this (safe)"), _("Restart Enlightenment"),
_("Quit Enlightenment"),
_("WARNING!!!!!!\n" "\n"
"Enlightenment attempted to free a NULL pointer.\n" "\n"
"This is definitely a bug. Please report it.\n"
"It is safe to ignore this error and continue running Enlightenment.\n"
"\n" "The pointer value was %x.\n"
"The error occurred at %s, line %d.\n"), ptr, file, line);
return;
}
free(ptr);
}
#endif
#endif /* !USE_LIBC_MALLOC */
#if !USE_LIBC_STRDUP
char *