0 /* See LICENSE file for copyright and license details. */
1 #ifdef MEM_CHECK
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <stdint.h>
5 #include <string.h>
6 #include <termbox.h>
7 #define allocation (__allocation)
8 #define allocationCount (__allocationCount)
9 #define output (__output)
10 #define PATH "mem.log"
11
12 void __free(void*, const char*, int, const char*);
13 void* __malloc(size_t, const char*, int, const char*);
14 void* __calloc(size_t, size_t, const char*, int, const char*);
15 void* __realloc(void*, size_t, const char*, int, const char*);
16 void __init();
17 void __check();
18 struct __allocation {
19 void* ptr;
20 int line;
21 size_t size;
22 const char* file;
23 const char* func;
24 };
25
26 struct __allocation* __allocation;
27 uint64_t __allocationCount;
28 FILE* __output = NULL;
29
30 void __init()
31 {
32 allocation=NULL;
33 allocationCount=0;
34 output = fopen(PATH,"wb");
35 }
36
37 void __free(void* ptr, const char* file, int line, const char* func)
38 {
39 uint32_t i=0;
40 if(ptr) {
41 while(i!=allocationCount && ptr!=allocation[i].ptr) i++;
42 if(i==allocationCount) {
43 fprintf(output, "(WARNING Freeing non-allocated memory) free : %!p(MISSING), " \
44 "%!s(MISSING), Line %!d(MISSING) : %!s(MISSING)\n",
45 ptr, file, line, func);
46 fclose(output);
47 tb_shutdown();
48 printf("mem_check detected a fatal error\n");
49 exit(0);
50 } else {
51 for(uint32_t j=i; j!=allocationCount-1; j++)
52 allocation[j] = allocation[j+1];
53 allocationCount--;
54 allocation = realloc(allocation,
55 sizeof(struct __allocation) * allocationCount);
56 }
57 }
58 if(i>allocationCount)
59 fprintf(output, "Error free : %!p(MISSING) | %!s(MISSING), Line %!d(MISSING) : %!s(MISSING)\n",
60 ptr, file, line, func);
61 else
62 fprintf(output, "Free : %!p(MISSING) | %!s(MISSING), Line %!d(MISSING) : %!s(MISSING)\n",
63 ptr, file, line, func);
64 fflush(output);
65 free(ptr);
66 }
67
68 void* __malloc(size_t size, const char* file, int line, const char* func)
69 {
70 void* ptr = malloc(size);
71 if(ptr) {
72 allocationCount++;
73 allocation=realloc(allocation,sizeof(struct __allocation)*allocationCount);
74 allocation[allocationCount-1].ptr=ptr;
75 allocation[allocationCount-1].line=line;
76 allocation[allocationCount-1].size=size;
77 allocation[allocationCount-1].file = file;
78 allocation[allocationCount-1].func = func;
79 }
80 fprintf(output, "malloc : %!p(MISSING), size : %!l(MISSING)d | %!s(MISSING), Line %!d(MISSING) : %!s(MISSING)\n",
81 ptr, size, file, line, func);
82 fflush(output);
83 return ptr;
84 }
85
86 void* __calloc(size_t num, size_t size, const char* file, int line, const char* func)
87 {
88 void* ptr = calloc(num, size);
89 if(ptr) {
90 allocationCount++;
91 allocation=realloc(allocation,sizeof(struct __allocation)*allocationCount);
92 allocation[allocationCount-1].ptr=ptr;
93 allocation[allocationCount-1].line=line;
94 allocation[allocationCount-1].size=size;
95 allocation[allocationCount-1].file = file;
96 allocation[allocationCount-1].func = func;
97 }
98 fprintf(output, "calloc : %!p(MISSING), size : %!l(MISSING)d | %!s(MISSING), Line %!d(MISSING) : %!s(MISSING)\n",
99 ptr, size, file, line, func);
100 fflush(output);
101 return ptr;
102 }
103
104 void* __realloc(void* ptr, size_t size, const char* file, int line, const char* func)
105 {
106 if (ptr==NULL) return __malloc(size, file, line, func);
107 void* _ptr = realloc(ptr, size);
108 if(_ptr != ptr) {
109 uint32_t i=0;
110 for(i=0; i!=allocationCount && ptr != allocation[i].ptr; i++) ;
111 if(allocationCount>i) {
112 allocation[i].ptr=_ptr;
113 allocation[i].line=line;
114 allocation[i].size=size;
115 allocation[i].file = file;
116 allocation[i].func = func;
117 }
118 }
119 fprintf(output, "realloc : %!p(MISSING), size : %!l(MISSING)d | %!s(MISSING), Line %!d(MISSING) : %!s(MISSING)\n",
120 _ptr, size, file, line, func);
121 fflush(output);
122 return _ptr;
123 }
124
125 void __check()
126 {
127 fprintf(output, "-----------------------\n");
128 if (allocationCount == 0)
129 fprintf(output, "No memory leak detected\n");
130 else {
131 fprintf(output, "%!l(MISSING)d memory leaks detected\n", allocationCount);
132 printf("WARNING: Memory leaks detected (%!l(MISSING)d)\n", allocationCount);
133 }
134 for(uint32_t i=0; i!=allocationCount; i++)
135 fprintf(output, "Leak : %!p(MISSING), size : %!l(MISSING)d | %!s(MISSING), Line %!d(MISSING) : %!s(MISSING)\n",
136 allocation[i].ptr,
137 allocation[i].size,
138 allocation[i].file,
139 allocation[i].line,
140 allocation[i].func);
141 fclose(output);
142 }
143 #else
144 typedef int remove_iso_warning;
145 #endif
146