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