#define _LARGEFILE64_SOURCE /* required for GLIBC to enable stat64 and friends */ #include #include #include #include #include #include #include #include #include #include #include #include "mt.h" #include "error.h" #include "globals.h" #include "term.h" #include "utils.h" #include "mem.h" #ifndef _DEBUG #define MEMLOG(x) void dump_mem(int sig) { } #else void MEMLOG(char *s, ...) { va_list ap; FILE *fh = fopen("log.log", "a+"); if (!fh) error_exit(__FILE__, __PRETTY_FUNCTION__, __LINE__, "error logging\n"); va_start(ap, s); vfprintf(fh, s, ap); va_end(ap); fclose(fh); } typedef struct { void *p; int size; char *file; char *function; int line; } memlist; memlist *pm = NULL; int n_pm = 0; void dump_mem(int sig) { int loop; signal(SIGHUP, dump_mem); if (sig != SIGHUP) error_exit(__FILE__, __PRETTY_FUNCTION__, __LINE__, "Unexpected signal %d.\n", sig); MEMLOG("%d elements of memory used\n", n_pm); for(loop=0; loop 0) memmove(&pm[loop], &pm[loop + 1], n_to_move * sizeof(memlist)); else if (n_to_move < 0) error_exit(__FILE__, __PRETTY_FUNCTION__, __LINE__, "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(__FILE__, __PRETTY_FUNCTION__, __LINE__, "Failed to shrink memory list to %d elements.\n", n_pm); } else { free(pm); pm = NULL; } } return old_size; } void add_mem_element(void *p, int size, char *file, const char *function, int line) { pm = (memlist *)realloc(pm, sizeof(memlist) * (n_pm + 1)); if (!pm) error_exit(__FILE__, __PRETTY_FUNCTION__, __LINE__, "Failed to grow memory list from %d elements.\n", n_pm); pm[n_pm].p = p; pm[n_pm].size = size; pm[n_pm].file = file; pm[n_pm].function = (char *)function; pm[n_pm].line = line; n_pm++; } #endif void myfree(void *p) { #ifdef _DEBUG (void)remove_mem_element(p); #endif free(p); } void * myrealloc(void *oldp, int new_size, char *file, const char *function, int line) { #ifdef _DEBUG int old_size; void *newp; if (new_size <= 0) error_exit(file, function, line, "Tried to allocate %d bytes which is wrong.\n", new_size); newp = realloc(oldp, new_size); if (!newp) error_exit(file, function, line, "Failed to reallocate a memory block to %d bytes.\n", new_size); old_size = remove_mem_element(oldp); add_mem_element(newp, new_size, file, function, line); signal(SIGHUP, dump_mem); if (new_size > old_size) memset(&((char *)newp)[old_size], 0xf1, new_size - old_size); /* rand_size = new_size - old_size; if (rand_size > 0) { MEMLOG("randomizing(%s) %d bytes\n", what, rand_size); memset(&((char *)newp)[old_size], rand_val, rand_size); } */ #else /* ---------------------------------------------------- * add code for repeatingly retry? -> then configurable * via configurationfile with number of retries and/or * sleep * ---------------------------------------------------- */ void *newp = realloc(oldp, new_size); if (!newp) error_exit(file, function, line, "Failed to reallocate a memory block to %d bytes.\n", new_size); #endif return newp; } void * mymalloc(int size, char *file, const char *function, int line) { return myrealloc(NULL, size, file, function, line); } char * mystrdup(char *in, char *file, const char *function, int line) { #ifdef _DEBUG int len = strlen(in) + 1; char *newp = (char *)mymalloc(len, file, function, line); memcpy(newp, in, len); return newp; #else char *newp = strdup(in); if (!newp) error_exit(file, function, line, "Failed to duplicate a string: out of memory?\n"); return newp; #endif } #ifdef _DEBUG void clean_memory(void) { int loop; /* color schemes */ for(loop=0; loop n_strip; loop2++) { if ((cur -> pstrip)[loop2].type == STRIP_TYPE_REGEXP || (cur -> pstrip)[loop2].type == STRIP_KEEP_SUBSTR) { regfree(&(cur -> pstrip)[loop2].regex); myfree ((cur -> pstrip)[loop2].regex_str); } myfree ((cur -> pstrip)[loop2].del); } myfree(cur -> pstrip); myfree(cur -> filename); for(loop2=0; loop2 n_redirect; loop2++) myfree((cur -> predir)[loop2].redirect); myfree(cur -> predir); myfree(cur -> label); free_iat(&cur -> conversions); myfree(cur -> incomplete_line); myfree(cur -> win_title); delete_array(cur -> restart.diff.bcur, cur -> restart.diff.ncur); delete_array(cur -> restart.diff.bprev, cur -> restart.diff.nprev); myfree(cur -> repeat.last_line); free_iat(&cur -> cdef.color_schemes); delete_popup(cur -> status); delete_popup(cur -> data); for(loop2=0; loop2 n_re; loop2++) free_re(&(cur -> pre)[loop2]); myfree(cur -> pre); cur = cur -> next; if (pcur != &pi[loop]) myfree(pcur); } } myfree(pi); /* parameters per file */ for(loop=0; loop script); myfree(conversions[loop].pcs); } myfree(conversions); /* filterschemes */ for(loop=0; loop