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);
85 static void add_mem_info(void *mem_ref, unsigned int size, const char *file, unsigned int line) {
86 SYNCHRONIZE(synchronized);
87 struct MemoryLeak *mem_leak_info = malloc(sizeof(*mem_leak_info));
88 own_allocated_memleaks++;
89 mem_leak_info->mem_info.address = mem_ref;
90 mem_leak_info->mem_info.size = size;
91 strcpy(mem_leak_info->mem_info.file_name, file);
92 mem_leak_info->mem_info.line = line;
93 mem_leak_info->next = ptr_start;
94 ptr_start = mem_leak_info;
95 DESYNCHRONIZE(synchronized);
98 static void remove_mem_info(void *mem_ref) {
99 SYNCHRONIZE(synchronized);
100 struct MemoryLeak *leak_info, *next, *prev = NULL;
101 for(leak_info = ptr_start; leak_info; leak_info = next) {
102 next = leak_info->next;
103 if (leak_info->mem_info.address == mem_ref) {
108 own_allocated_memleaks--;
114 DESYNCHRONIZE(synchronized);
117 void initMemoryDebug() {
118 THREAD_MUTEX_INIT(synchronized);
121 struct memoryInfoFiles *getMemoryInfoFiles() {
122 SYNCHRONIZE(synchronized);
123 struct MemoryLeak *leak_info;
124 struct memoryInfoFiles *list = NULL, *element;
125 for(leak_info = ptr_start; leak_info != NULL; leak_info = leak_info->next) {
126 for(element = list; element; element = element->next) {
127 if(!strcmp(leak_info->mem_info.file_name, element->filename)) {
132 element = malloc(sizeof(*element));
133 element->filename = strdup(leak_info->mem_info.file_name);
134 element->allocations = 0;
135 element->allocated = 0;
136 element->next = list;
139 element->allocations += 1;
140 element->allocated += leak_info->mem_info.size;
142 element = malloc(sizeof(*element));
143 element->filename = strdup(__FILE__);
144 element->allocations = own_allocated_memleaks;
145 element->allocated = own_allocated_memleaks * sizeof(struct MemoryLeak);
146 element->next = list;
148 DESYNCHRONIZE(synchronized);
152 void freeMemoryInfoFiles(struct memoryInfoFiles *files) {
153 struct memoryInfoFiles *next;
154 for(;files;files = next) {
156 free(files->filename);
161 struct memoryInfoLines *getMemoryInfoLines(const char *filename) {
162 SYNCHRONIZE(synchronized);
163 struct MemoryLeak *leak_info;
164 struct memoryInfoLines *list = NULL, *element;
165 for(leak_info = ptr_start; leak_info != NULL; leak_info = leak_info->next) {
166 if(stricmp(leak_info->mem_info.file_name, filename)) continue;
167 for(element = list; element; element = element->next) {
168 if(element->line == leak_info->mem_info.line && element->allocate == leak_info->mem_info.size) {
173 element = malloc(sizeof(*element));
174 element->line = leak_info->mem_info.line;
175 element->allocations = 0;
176 element->allocate = leak_info->mem_info.size;
177 element->next = list;
180 element->allocations++;
182 if(!stricmp(filename, __FILE__)) {
183 element = malloc(sizeof(*element));
185 element->allocations = own_allocated_memleaks;
186 element->allocate = sizeof(struct MemoryLeak);
187 element->next = list;
190 DESYNCHRONIZE(synchronized);
194 void freeMemoryInfoLines(struct memoryInfoLines *lines) {
195 struct memoryInfoLines *next;
196 for(;lines;lines = next) {