1 /* memoryDebug.c - NeonServ v5.3
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 void add_mem_info(void * mem_ref, unsigned int size, const char *file, unsigned int line);
48 static void remove_mem_info(void * mem_ref);
50 void *xmalloc(unsigned int size, const char *file, unsigned int line) {
51 void *ptr = malloc(size);
53 add_mem_info(ptr, size, file, line);
58 void *xcalloc(unsigned int elements, unsigned int size, const char *file, unsigned int line) {
59 void *ptr = calloc(elements, size);
61 add_mem_info(ptr, (elements * size), file, line);
66 char *xstrdup(const char *data, const char *file, unsigned int line) {
67 int len = strlen(data)+1;
68 char *ptr = malloc(len);
71 add_mem_info(ptr, len, file, line);
76 void xfree(void *mem_ref) {
77 remove_mem_info(mem_ref);
82 static void add_mem_info(void *mem_ref, unsigned int size, const char *file, unsigned int line) {
83 SYNCHRONIZE(synchronized);
84 struct MemoryLeak *mem_leak_info = malloc (sizeof(*mem_leak_info));
85 mem_leak_info->mem_info.address = mem_ref;
86 mem_leak_info->mem_info.size = size;
87 strcpy(mem_leak_info->mem_info.file_name, file);
88 mem_leak_info->mem_info.line = line;
89 mem_leak_info->next = ptr_start;
90 ptr_start = mem_leak_info;
91 DESYNCHRONIZE(synchronized);
94 static void remove_mem_info(void *mem_ref) {
95 SYNCHRONIZE(synchronized);
96 struct MemoryLeak *leak_info, *next, *prev = NULL;
97 for(leak_info = ptr_start; leak_info; leak_info = next) {
98 next = leak_info->next;
99 if (leak_info->mem_info.address == mem_ref) {
109 DESYNCHRONIZE(synchronized);
112 void report_mem_leak() {
113 SYNCHRONIZE(synchronized);
114 struct MemoryLeak *leak_info;
115 FILE *fp_write = fopen(OUTPUT_FILE, "wt");
118 if(fp_write != NULL) {
119 sprintf(info, "%s\n", "Memory Leak Summary");
120 fwrite(info, (strlen(info)) , 1, fp_write);
121 sprintf(info, "%s\n", "-----------------------------------");
122 fwrite(info, (strlen(info)) , 1, fp_write);
124 for(leak_info = ptr_start; leak_info != NULL; leak_info = leak_info->next) {
125 sprintf(info, "address : %p\n", leak_info->mem_info.address);
126 fwrite(info, (strlen(info)) , 1, fp_write);
127 sprintf(info, "size : %d bytes\n", leak_info->mem_info.size);
128 fwrite(info, (strlen(info)) , 1, fp_write);
129 sprintf(info, "file : %s\n", leak_info->mem_info.file_name);
130 fwrite(info, (strlen(info)) , 1, fp_write);
131 sprintf(info, "line : %d\n", leak_info->mem_info.line);
132 fwrite(info, (strlen(info)) , 1, fp_write);
133 sprintf(info, "%s\n", "-----------------------------------");
134 fwrite(info, (strlen(info)) , 1, fp_write);
138 DESYNCHRONIZE(synchronized);
141 void initMemoryDebug() {
142 THREAD_MUTEX_INIT(synchronized);
145 struct memoryInfoFiles *getMemoryInfoFiles() {
146 SYNCHRONIZE(synchronized);
147 struct MemoryLeak *leak_info;
148 struct memoryInfoFiles *list = NULL, *element;
149 for(leak_info = ptr_start; leak_info != NULL; leak_info = leak_info->next) {
150 for(element = list; element; element = element->next) {
151 if(!strcmp(leak_info->mem_info.file_name, element->filename)) {
156 element = malloc(sizeof(*element));
157 element->filename = strdup(leak_info->mem_info.file_name);
158 element->allocations = 0;
159 element->allocated = 0;
160 element->next = list;
163 element->allocations += 1;
164 element->allocated += leak_info->mem_info.size;
166 DESYNCHRONIZE(synchronized);
170 void freeMemoryInfoFiles(struct memoryInfoFiles *files) {
171 struct memoryInfoFiles *next;
172 for(;files;files = next) {
174 free(files->filename);
179 struct memoryInfoLines *getMemoryInfoLines(const char *filename) {
180 SYNCHRONIZE(synchronized);
181 struct MemoryLeak *leak_info;
182 struct memoryInfoLines *list = NULL, *element;
183 for(leak_info = ptr_start; leak_info != NULL; leak_info = leak_info->next) {
184 if(stricmp(leak_info->mem_info.file_name, filename)) continue;
185 for(element = list; element; element = element->next) {
186 if(element->line == leak_info->mem_info.line && element->allocate == leak_info->mem_info.size) {
191 element = malloc(sizeof(*element));
192 element->line = leak_info->mem_info.line;
193 element->allocations = 0;
194 element->allocate = leak_info->mem_info.size;
195 element->next = list;
198 element->allocations++;
200 DESYNCHRONIZE(synchronized);
204 void freeMemoryInfoLines(struct memoryInfoLines *lines) {
205 struct memoryInfoLines *next;
206 for(;lines;lines = next) {