Go Back

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 int __main(int argc, char* argv[]);

19

20 struct __allocation {

21 void* ptr;

22 int line;

23 size_t size;

24 const char* file;

25 const char* func;

26 };

27

28 int main(int argc, char* argv[]) {

29 __init();

30 int ret = __main(argc, argv);

31 __check();

32 return ret;

33 }

34

35 struct __allocation* __allocation;

36 uint64_t __allocationCount;

37 FILE* __output = NULL;

38 int __warnings = 0;

39

40 void __debug(const char* out) {

41 fprintf(output, out);

42 fflush(output);

43 }

44

45 void __init() {

46 allocation=NULL;

47 allocationCount=0;

48 output = fopen(PATH,"wb");

49 }

50

51 void __free(void* ptr, const char* file, int line, const char* func) {

52 uint32_t i=0;

53 if(ptr) {

54 while(i!=allocationCount && ptr!=allocation[i].ptr) i++;

55 if(i==allocationCount) {

56 fprintf(output,

57 "(WARNING Freeing non-allocated memory) " \

58 "free : %p, %s, Line %d : %s\n",

59 ptr, file, line, func);

60 fflush(output);

61 #ifndef EXIT_ON_ERROR

62 __warnings++;

63 return;

64 #else

65 fclose(output);

66 tb_shutdown();

67 printf("mem_check detected a fatal error\n");

68 return exit(0);

69 #endif

70 }

71 for(uint32_t j=i; j!=allocationCount-1; j++)

72 allocation[j] = allocation[j+1];

73 allocationCount--;

74 allocation = realloc(allocation,

75 sizeof(struct __allocation) *

76 allocationCount);

77 }

78 if(i>allocationCount)

79 fprintf(output, "Error free : %p | %s, Line %d : %s\n",

80 ptr, file, line, func);

81 else

82 fprintf(output, "Free : %p | %s, Line %d : %s\n",

83 ptr, file, line, func);

84 fflush(output);

85 free(ptr);

86 }

87

88 void* __malloc(size_t size, const char* file, int line, const char* func) {

89 void* ptr = malloc(size);

90 if(ptr) {

91 allocationCount++;

92 allocation = realloc(allocation,

93 sizeof(struct __allocation) *

94 allocationCount);

95 allocation[allocationCount-1].ptr = ptr;

96 allocation[allocationCount-1].line = line;

97 allocation[allocationCount-1].size = size;

98 allocation[allocationCount-1].file = file;

99 allocation[allocationCount-1].func = func;

100 }

101 fprintf(output, "malloc : %p, size : %ld | %s, Line %d : %s\n",

102 ptr, size, file, line, func);

103 fflush(output);

104 return ptr;

105 }

106

107 void* __calloc(size_t num, size_t size, const char* file,

108 int line, const char* func) {

109 void* ptr = calloc(num, size);

110 if(ptr) {

111 allocationCount++;

112 allocation = realloc(allocation,

113 sizeof(struct __allocation) *

114 allocationCount);

115 allocation[allocationCount-1].ptr = ptr;

116 allocation[allocationCount-1].line = line;

117 allocation[allocationCount-1].size = size;

118 allocation[allocationCount-1].file = file;

119 allocation[allocationCount-1].func = func;

120 }

121 fprintf(output, "calloc : %p, size : %ld | %s, Line %d : %s\n",

122 ptr, size, file, line, func);

123 fflush(output);

124 return ptr;

125 }

126

127 void* __realloc(void* ptr, size_t size, const char* file,

128 int line, const char* func) {

129 if (ptr==NULL) return __malloc(size, file, line, func);

130 void* _ptr = realloc(ptr, size);

131 if(_ptr != ptr) {

132 uint32_t i=0;

133 for(i=0; i!=allocationCount && ptr != allocation[i].ptr; i++) ;

134 if(allocationCount>i) {

135 allocation[i].ptr = _ptr;

136 allocation[i].line = line;

137 allocation[i].size = size;

138 allocation[i].file = file;

139 allocation[i].func = func;

140 }

141 }

142 fprintf(output, "realloc : %p, size : %ld | %s, Line %d : %s\n",

143 _ptr, size, file, line, func);

144 fflush(output);

145 return _ptr;

146 }

147

148 void __check() {

149 fprintf(output, "-----------------------\n");

150 if (allocationCount == 0)

151 fprintf(output, "No memory leak detected\n");

152 else {

153 fprintf(output, "%ld memory leaks detected\n",

154 allocationCount);

155 printf("WARNING: Memory leaks detected (%ld)\n",

156 allocationCount);

157 }

158 if (__warnings) {

159 fprintf(output, "%d invalid memory operations detected\n",

160 __warnings);

161 printf("WARNING: %d invalid memory operations detected\n",

162 __warnings);

163 }

164 for(uint32_t i=0; i!=allocationCount; i++)

165 fprintf(output, "Leak : %p, size : %ld | %s, Line %d : %s\n",

166 allocation[i].ptr,

167 allocation[i].size,

168 allocation[i].file,

169 allocation[i].line,

170 allocation[i].func);

171 fclose(output);

172 }

173 #else

174 typedef int remove_iso_warning;

175 #endif

176