1 #ifndef __debug_h__
2 #define __debug_h__
3
4 void* ___d_malloc(size_t, const char*, int);
5 void* ___d_realloc(void*, size_t, const char*, int);
6 void ___d_free(void*, const char*, int);
7 char* ___d_strdup(const char*, const char*, int);
8 void ___d_exit(int);
9
10 #ifdef __implement__
11
12 struct ___d_meminfo {
13 unsigned long magic;
14 const char* fname;
15 int line;
16 size_t size;
17 struct ___d_meminfo* next;
18 struct ___d_meminfo* before;
19 };
20
21 static struct ___d_meminfo* ___d_meminfo_f = NULL;
22 static struct ___d_meminfo* ___d_meminfo_l = NULL;
23
24 void*
___d_malloc(size_t size,const char * fname,int line)25 ___d_malloc(size_t size, const char* fname, int line)
26 {
27 void* pv = malloc(size + sizeof(struct ___d_meminfo));
28 struct ___d_meminfo* info;
29 if (NULL == pv) {
30 fprintf(stderr, "%s(%d):%s\n", fname, line, "*** malloc failed ***\n");
31 fflush(stderr);
32 return NULL;
33 }
34 info = (struct ___d_meminfo*)pv;
35 info->magic = (unsigned long)'Samy';
36 info->fname = fname;
37 info->line = line;
38 info->size = size;
39 info->next = NULL;
40 info->before = NULL;
41 if (NULL == ___d_meminfo_f) {
42 ___d_meminfo_f = ___d_meminfo_l = info;
43 } else {
44 ___d_meminfo_l->next = info;
45 info->before = ___d_meminfo_l;
46 ___d_meminfo_l = info;
47 }
48 info++;
49 return (void*)info;
50 }
51
52 void*
___d_realloc(void * pv,size_t size,const char * fname,int line)53 ___d_realloc(void* pv, size_t size, const char* fname, int line)
54 {
55 void* result;
56 struct ___d_meminfo* info = (struct ___d_meminfo*)pv;
57 info--;
58 if (info->magic != (unsigned long)'Samy') {
59 fprintf(stderr, "%s(%d):%s\n", fname, line, "*** realloc called with invalid pv ***\n");
60 fflush(stderr);
61 return realloc(pv, size);
62 }
63 result = ___d_malloc(size, fname, line);
64 if (NULL == result) {
65 ___d_free(pv, fname, line);
66 return NULL;
67 }
68 memcpy(result, pv, info->size);
69 info->size = size;
70 ___d_free(pv, fname, line);
71 return result;
72 }
73
74 void
___d_free(void * pv,const char * fname,int line)75 ___d_free(void* pv, const char* fname, int line)
76 {
77 struct ___d_meminfo* info;
78 if (NULL == pv) return;
79 info = (struct ___d_meminfo*)pv;
80 info--;
81 if (info->magic != (unsigned long)'Samy') {
82 fprintf(stderr, "%s(%d):%s\n", fname, line, "*** free called with invalid pv ***\n");
83 fflush(stderr);
84 return free(pv);
85 /*
86 } else {
87 fprintf(stderr, "%s(%d):free %s(%d)\n", fname, line, info->fname, info->line);
88 fflush(stderr);
89 */
90 }
91 info->magic = 0;
92 if (NULL != info->next) info->next->before = info->before;
93 if (NULL != info->before) info->before->next = info->next;
94 if (___d_meminfo_f == info) ___d_meminfo_f = info->next;
95 if (___d_meminfo_l == info) ___d_meminfo_l = info->before;
96 free(info);
97 }
98
99 char*
___d_strdup(const char * c,const char * fname,int line)100 ___d_strdup(const char* c, const char* fname, int line)
101 {
102 int size = strlen(c);
103 char* result = (char*)___d_malloc(size + 1, fname, line);
104 if (NULL != result) {
105 memcpy(result, c, size);
106 result[size] = 0;
107 }
108 return result;
109 }
110
111 void
___d_exit(int code)112 ___d_exit(int code)
113 {
114 struct ___d_meminfo* p = ___d_meminfo_f;
115 char* data;
116 unsigned int ui;
117
118 if (NULL != p) {
119 fprintf(stderr, "*** memory leak detect ***\n");
120 for (; NULL != p; p = p->next) {
121 data = (char*)(&p[1]);
122 fprintf(stderr, "%s(%d):0x%08x %dbyte(s) [", p->fname, p->line, &p[1], p->size);
123 for (ui = 0; ui < p->size; ui++) {
124 fprintf(stderr, "%c", data[ui]);
125 if (ui == 7) {
126 fprintf(stderr, "...");
127 break;
128 }
129 }
130 fprintf(stderr,"(");
131 for (ui = 0; ui < p->size; ui++) {
132 fprintf(stderr, "%02x", data[ui] & 0xff);
133 if (ui == 7) {
134 fprintf(stderr, "...");
135 break;
136 }
137 }
138 fprintf(stderr, ")]\n");
139 }
140 }
141 exit(code);
142 }
143
144 #endif /* __implement__ */
145
146 #define malloc(s) ___d_malloc(s,__FILE__,__LINE__)
147 #define realloc(v,s) ___d_realloc(v,s,__FILE__,__LINE__)
148 #define free(v) ___d_free(v,__FILE__,__LINE__)
149 #define strdup(c) ___d_strdup(c,__FILE__,__LINE__)
150 #define exit(i) ___d_exit(i)
151
152 #endif /* __debug_h__ */
153