/* (C) 2007 by folkert@vanheusden.com
* The GPL (GNU public license) applies to this sourcecode.
*/
#include <errno.h>
#include <regex.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
static void error_exit(char *format, ...)
{
va_list ap;
va_start(ap, format);
(void)vfprintf(stderr, format, ap);
va_end(ap);
if (errno)
fprintf(stderr, "errno: %d=%s (if applicable)\n", errno, strerror(errno));
exit(EXIT_FAILURE);
}
static void MEMLOG(char *s, ...)
{
va_list ap;
FILE *fh = fopen("log.log", "a+");
if (!fh)
error_exit("error logging\n");
va_start(ap, s);
vfprintf(fh, s, ap);
va_end(ap);
fclose(fh);
}
typedef struct
{
void *p;
char *descr;
int size;
} memlist;
memlist *pm = NULL;
int n_pm = 0;
void dump_mem(int sig)
{
int loop;
signal(SIGHUP, dump_mem);
if (sig != SIGHUP)
error_exit("dump_mem: unexpected signal %d for dump_mem\n", sig);
MEMLOG("%d elements of memory used\n", n_pm);
for(loop=0; loop<n_pm; loop++)
{
MEMLOG("%06d] %p %d (%s)\n", loop, pm[loop].p, pm[loop].size, pm[loop].descr);
}
MEMLOG("--- finished memory dump\n");
}
static int remove_mem_element(void *p)
{
int old_size = 0;
if (p)
{
int loop;
for(loop=0; loop<n_pm; loop++)
{
if (pm[loop].p == p)
{
int n_to_move;
old_size = pm[loop].size;
n_to_move = (n_pm - loop) - 1;
if (n_to_move > 0)
memmove(&pm[loop], &pm[loop + 1], n_to_move * sizeof(memlist));
else if (n_to_move < 0)
error_exit("remove_mem_element: n_to_move < 0!\n");
n_pm--;
loop=-1;
break;
}
}
if (loop != -1)
{
MEMLOG("remove_mem_element: pointer %p not found\n", p);
}
if (n_pm)
{
pm = (memlist *)realloc(pm, sizeof(memlist) * n_pm);
if (!pm) error_exit("remove_mem_element: failed to shrink memorylist to %d elements\n", n_pm);
}
else
{
free(pm);
pm = NULL;
}
}
return old_size;
}
static void add_mem_element(void *p, int size, char *what)
{
pm = (memlist *)realloc(pm, sizeof(memlist) * (n_pm + 1));
if (!pm) error_exit("add_mem_element: failed to grow memorylist from %d elements\n", n_pm);
pm[n_pm].p = p;
pm[n_pm].size = size;
pm[n_pm].descr = what;
n_pm++;
}
void myfree(void *p)
{
int old_size = remove_mem_element(p);
MEMLOG("myfree: %p (%d bytes)\n", p, old_size);
memset(p, 0xf3, old_size);
free(p);
}
void * myrealloc(void *oldp, int new_size, char *what)
{
int old_size;
void *newp;
if (new_size <= 0)
error_exit("Tried to allocate %d bytes which is wrong.\n", new_size);
newp = realloc(oldp, new_size);
if (!newp)
error_exit("Failed to reallocate a memory block to %d bytes.\n", new_size);
old_size = remove_mem_element(oldp);
add_mem_element(newp, new_size, what);
signal(SIGHUP, dump_mem);
if (new_size > old_size)
memset(&((char *)newp)[old_size], 0xf1, new_size - old_size);
return newp;
}
void * mymalloc(int size, char *what)
{
return myrealloc(NULL, size, what);
}
char * mystrdup(char *in, char *what)
{
int len = strlen(in) + 1;
char *newp = (char *)mymalloc(len, what);
memcpy(newp, in, len);
return newp;
}
syntax highlighted by Code2HTML, v. 0.9.1