1 /* memoryDebug.c - NeonServ v5.6
2 * Copyright (C) 2011-2012 Philipp Kreil (pk910)
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "memoryDebug.h"
19 #include "memoryInfo.h"
22 #define FILE_NAME_LENGTH 256
23 #define OUTPUT_FILE "leak_info.txt"
33 char file_name[FILE_NAME_LENGTH];
38 struct MemoryNode mem_info;
39 struct MemoryLeak *next;
43 static pthread_mutex_t synchronized;
46 static struct MemoryLeak *ptr_start = NULL;
48 static unsigned int own_allocated_memleaks = 0;
50 static void add_mem_info(void * mem_ref, unsigned int size, const char *file, unsigned int line);
51 static void remove_mem_info(void * mem_ref);
53 void *xmalloc(unsigned int size, const char *file, unsigned int line) {
54 void *ptr = malloc(size);
56 add_mem_info(ptr, size, file, line);
61 void *xcalloc(unsigned int elements, unsigned int size, const char *file, unsigned int line) {
62 void *ptr = calloc(elements, size);
64 add_mem_info(ptr, (elements * size), file, line);
69 char *xstrdup(const char *data, const char *file, unsigned int line) {
70 int len = strlen(data)+1;
71 char *ptr = malloc(len);
74 add_mem_info(ptr, len, file, line);
79 void xfree(void *mem_ref) {
80 remove_mem_info(mem_ref);
84 static void add_mem_info(void *mem_ref, unsigned int size, const char *file, unsigned int line) {
86 pthread_mutex_lock(&synchronized);
88 struct MemoryLeak *mem_leak_info = malloc(sizeof(*mem_leak_info));
89 own_allocated_memleaks++;
90 mem_leak_info->mem_info.address = mem_ref;
91 mem_leak_info->mem_info.size = size;
92 strcpy(mem_leak_info->mem_info.file_name, file);
93 mem_leak_info->mem_info.line = line;
94 mem_leak_info->next = ptr_start;
95 ptr_start = mem_leak_info;
97 pthread_mutex_unlock(&synchronized);
101 static void remove_mem_info(void *mem_ref) {
103 pthread_mutex_lock(&synchronized);
105 struct MemoryLeak *leak_info, *next, *prev = NULL;
106 for(leak_info = ptr_start; leak_info; leak_info = next) {
107 next = leak_info->next;
108 if (leak_info->mem_info.address == mem_ref) {
113 own_allocated_memleaks--;
120 pthread_mutex_unlock(&synchronized);
124 void initMemoryDebug() {
125 THREAD_MUTEX_INIT(synchronized);
128 struct memoryInfoFiles *getMemoryInfoFiles() {
130 pthread_mutex_lock(&synchronized);
132 struct MemoryLeak *leak_info;
133 struct memoryInfoFiles *list = NULL, *element;
134 for(leak_info = ptr_start; leak_info != NULL; leak_info = leak_info->next) {
135 for(element = list; element; element = element->next) {
136 if(!strcmp(leak_info->mem_info.file_name, element->filename)) {
141 element = malloc(sizeof(*element));
142 element->filename = strdup(leak_info->mem_info.file_name);
143 element->allocations = 0;
144 element->allocated = 0;
145 element->next = list;
148 element->allocations += 1;
149 element->allocated += leak_info->mem_info.size;
151 element = malloc(sizeof(*element));
152 element->filename = strdup(__FILE__);
153 element->allocations = own_allocated_memleaks;
154 element->allocated = own_allocated_memleaks * sizeof(struct MemoryLeak);
155 element->next = list;
158 pthread_mutex_unlock(&synchronized);
163 void freeMemoryInfoFiles(struct memoryInfoFiles *files) {
164 struct memoryInfoFiles *next;
165 for(;files;files = next) {
167 free(files->filename);
172 struct memoryInfoLines *getMemoryInfoLines(const char *filename) {
174 pthread_mutex_lock(&synchronized);
176 struct MemoryLeak *leak_info;
177 struct memoryInfoLines *list = NULL, *element;
178 for(leak_info = ptr_start; leak_info != NULL; leak_info = leak_info->next) {
179 if(stricmp(leak_info->mem_info.file_name, filename)) continue;
180 for(element = list; element; element = element->next) {
181 if(element->line == leak_info->mem_info.line && element->allocate == leak_info->mem_info.size) {
186 element = malloc(sizeof(*element));
187 element->line = leak_info->mem_info.line;
188 element->allocations = 0;
189 element->allocate = leak_info->mem_info.size;
190 element->next = list;
193 element->allocations++;
195 if(!stricmp(filename, __FILE__)) {
196 element = malloc(sizeof(*element));
198 element->allocations = own_allocated_memleaks;
199 element->allocate = sizeof(struct MemoryLeak);
200 element->next = list;
204 pthread_mutex_unlock(&synchronized);
209 void freeMemoryInfoLines(struct memoryInfoLines *lines) {
210 struct memoryInfoLines *next;
211 for(;lines;lines = next) {