1 /* memoryDebug.c - NeonServ v5.4
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"
21 #define FILE_NAME_LENGTH 256
22 #define OUTPUT_FILE "leak_info.txt"
32 char file_name[FILE_NAME_LENGTH];
37 struct MemoryNode mem_info;
38 struct MemoryLeak *next;
42 static pthread_mutex_t synchronized;
45 static struct MemoryLeak *ptr_start = NULL;
47 static unsigned int own_allocated_memleaks = 0;
49 static void add_mem_info(void * mem_ref, unsigned int size, const char *file, unsigned int line);
50 static void remove_mem_info(void * mem_ref);
52 void *xmalloc(unsigned int size, const char *file, unsigned int line) {
53 void *ptr = malloc(size);
55 add_mem_info(ptr, size, file, line);
60 void *xcalloc(unsigned int elements, unsigned int size, const char *file, unsigned int line) {
61 void *ptr = calloc(elements, size);
63 add_mem_info(ptr, (elements * size), file, line);
68 char *xstrdup(const char *data, const char *file, unsigned int line) {
69 int len = strlen(data)+1;
70 char *ptr = malloc(len);
73 add_mem_info(ptr, len, file, line);
78 void xfree(void *mem_ref) {
79 remove_mem_info(mem_ref);
84 static void add_mem_info(void *mem_ref, unsigned int size, const char *file, unsigned int line) {
85 SYNCHRONIZE(synchronized);
86 struct MemoryLeak *mem_leak_info = malloc(sizeof(*mem_leak_info));
87 own_allocated_memleaks++;
88 mem_leak_info->mem_info.address = mem_ref;
89 mem_leak_info->mem_info.size = size;
90 strcpy(mem_leak_info->mem_info.file_name, file);
91 mem_leak_info->mem_info.line = line;
92 mem_leak_info->next = ptr_start;
93 ptr_start = mem_leak_info;
94 DESYNCHRONIZE(synchronized);
97 static void remove_mem_info(void *mem_ref) {
98 SYNCHRONIZE(synchronized);
99 struct MemoryLeak *leak_info, *next, *prev = NULL;
100 for(leak_info = ptr_start; leak_info; leak_info = next) {
101 next = leak_info->next;
102 if (leak_info->mem_info.address == mem_ref) {
107 own_allocated_memleaks--;
113 DESYNCHRONIZE(synchronized);
116 void initMemoryDebug() {
117 THREAD_MUTEX_INIT(synchronized);
120 struct memoryInfoFiles *getMemoryInfoFiles() {
121 SYNCHRONIZE(synchronized);
122 struct MemoryLeak *leak_info;
123 struct memoryInfoFiles *list = NULL, *element;
124 for(leak_info = ptr_start; leak_info != NULL; leak_info = leak_info->next) {
125 for(element = list; element; element = element->next) {
126 if(!strcmp(leak_info->mem_info.file_name, element->filename)) {
131 element = malloc(sizeof(*element));
132 element->filename = strdup(leak_info->mem_info.file_name);
133 element->allocations = 0;
134 element->allocated = 0;
135 element->next = list;
138 element->allocations += 1;
139 element->allocated += leak_info->mem_info.size;
141 element = malloc(sizeof(*element));
142 element->filename = strdup(__FILE__);
143 element->allocations = own_allocated_memleaks;
144 element->allocated = own_allocated_memleaks * sizeof(struct MemoryLeak);
145 element->next = list;
147 DESYNCHRONIZE(synchronized);
151 void freeMemoryInfoFiles(struct memoryInfoFiles *files) {
152 struct memoryInfoFiles *next;
153 for(;files;files = next) {
155 free(files->filename);
160 struct memoryInfoLines *getMemoryInfoLines(const char *filename) {
161 SYNCHRONIZE(synchronized);
162 struct MemoryLeak *leak_info;
163 struct memoryInfoLines *list = NULL, *element;
164 for(leak_info = ptr_start; leak_info != NULL; leak_info = leak_info->next) {
165 if(stricmp(leak_info->mem_info.file_name, filename)) continue;
166 for(element = list; element; element = element->next) {
167 if(element->line == leak_info->mem_info.line && element->allocate == leak_info->mem_info.size) {
172 element = malloc(sizeof(*element));
173 element->line = leak_info->mem_info.line;
174 element->allocations = 0;
175 element->allocate = leak_info->mem_info.size;
176 element->next = list;
179 element->allocations++;
181 if(!stricmp(filename, __FILE__)) {
182 element = malloc(sizeof(*element));
184 element->allocations = own_allocated_memleaks;
185 element->allocate = sizeof(struct MemoryLeak);
186 element->next = list;
189 DESYNCHRONIZE(synchronized);
193 void freeMemoryInfoLines(struct memoryInfoLines *lines) {
194 struct memoryInfoLines *next;
195 for(;lines;lines = next) {