1 #undef	_MEMORY_DEBUG_
2 #include	"psqlodbc.h"
3 
4 #ifdef	WIN32
5 #ifdef	_DEBUG
6 /* #include	<stdlib.h> */
7 #define	_CRTDBG_MAP_ALLOC
8 #include <crtdbg.h>
9 #else
10 #include	<malloc.h>
11 #endif /* _DEBUG */
12 #endif /* WIN32 */
13 #include	<string.h>
14 
15 #include	"misc.h"
16 typedef struct {
17 	size_t	len;
18 	void	*aladr;
19 } ALADR;
20 
21 static int	alsize = 0;
22 static int	tbsize = 0;
23 static ALADR	*altbl = NULL;
24 
25 CSTR	ALCERR	= "alcerr";
pgdebug_alloc(size_t size)26 void * pgdebug_alloc(size_t size)
27 {
28 	void * alloced;
29 	alloced = malloc(size);
30 MYLOG(2, " alloced=%p(" FORMAT_SIZE_T ")\n", alloced, size);
31 	if (alloced)
32 	{
33 		if (!alsize)
34 		{
35 			alsize = 100;
36 			altbl = (ALADR *) malloc(alsize * sizeof(ALADR));
37 		}
38 		else if (tbsize >= alsize)
39 		{
40 			ALADR *al;
41 			alsize *= 2;
42 			if (al = (ALADR *) realloc(altbl, alsize * sizeof(ALADR)), NULL == al)
43 				return alloced;
44 			altbl = al;
45 		}
46 		altbl[tbsize].aladr = alloced;
47 		altbl[tbsize].len = size;
48 		tbsize++;
49 	}
50 	else
51 		MYLOG(0, "%s:alloc " FORMAT_SIZE_T "byte\n", ALCERR, size);
52 	return alloced;
53 }
pgdebug_calloc(size_t n,size_t size)54 void * pgdebug_calloc(size_t n, size_t size)
55 {
56 	void * alloced = calloc(n, size);
57 
58 	if (alloced)
59 	{
60 		if (!alsize)
61 		{
62 			alsize = 100;
63 			altbl = (ALADR *) malloc(alsize * sizeof(ALADR));
64 		}
65 		else if (tbsize >= alsize)
66 		{
67 			ALADR *al;
68 			alsize *= 2;
69 			if (al = (ALADR *) realloc(altbl, alsize * sizeof(ALADR)), NULL == al)
70 				return alloced;
71 			altbl = al;
72 		}
73 		altbl[tbsize].aladr = alloced;
74 		altbl[tbsize].len = n * size;
75 		tbsize++;
76 	}
77 	else
78 		MYLOG(0, "%s:calloc " FORMAT_SIZE_T "byte\n", ALCERR, size);
79 MYLOG(2, "calloced = %p\n", alloced);
80 	return alloced;
81 }
pgdebug_realloc(void * ptr,size_t size)82 void * pgdebug_realloc(void * ptr, size_t size)
83 {
84 	void * alloced;
85 
86 	if (!ptr)
87 		return pgdebug_alloc(size);
88 	alloced = realloc(ptr, size);
89 	if (!alloced)
90 	{
91 		MYLOG(0, "%s %p error\n", ALCERR, ptr);
92 	}
93 	else /* if (alloced != ptr) */
94 	{
95 		int	i;
96 		for (i = 0; i < tbsize; i++)
97 		{
98 			if (altbl[i].aladr == ptr)
99 			{
100 				altbl[i].aladr = alloced;
101 				altbl[i].len = size;
102 				break;
103 			}
104 		}
105 	}
106 
107 	MYLOG(2, "%p->%p\n", ptr, alloced);
108 	return alloced;
109 }
pgdebug_strdup(const char * ptr)110 char * pgdebug_strdup(const char * ptr)
111 {
112 	char * alloced = strdup(ptr);
113 	if (!alloced)
114 	{
115 		MYLOG(0, "%s %p error\n", ALCERR, ptr);
116 	}
117 	else
118 	{
119 		if (!alsize)
120 		{
121 			alsize = 100;
122 			altbl = (ALADR *) malloc(alsize * sizeof(ALADR));
123 		}
124 		else if (tbsize >= alsize)
125 		{
126 			ALADR *al;
127 			alsize *= 2;
128 			if (al = (ALADR *) realloc(altbl, alsize * sizeof(ALADR)), NULL == al)
129 				return alloced;
130 			altbl = al;
131 		}
132 		altbl[tbsize].aladr = alloced;
133 		altbl[tbsize].len = strlen(ptr) + 1;
134 		tbsize++;
135 	}
136 	MYLOG(2, "%p->%p(%s)\n", ptr, alloced, alloced);
137 	return alloced;
138 }
139 
pgdebug_free(void * ptr)140 void pgdebug_free(void * ptr)
141 {
142 	int i, j;
143 	int	freed = 0;
144 
145 	if (!ptr)
146 	{
147 		MYLOG(0, "%s null ptr\n", ALCERR);
148 		return;
149 	}
150 	for (i = 0; i < tbsize; i++)
151 	{
152 		if (altbl[i].aladr == ptr)
153 		{
154 			for (j = i; j < tbsize - 1; j++)
155 			{
156 				altbl[j].aladr = altbl[j + 1].aladr;
157 				altbl[j].len = altbl[j + 1].len;
158 			}
159 			tbsize--;
160 			freed = 1;
161 			break;
162 		}
163 	}
164 	if (! freed)
165 	{
166 		MYLOG(0, "%s not found ptr %p\n", ALCERR, ptr);
167 		return;
168 	}
169 	else
170 		MYLOG(2, "ptr=%p\n", ptr);
171 	free(ptr);
172 }
173 
out_check(void * out,size_t len,const char * name)174 static BOOL out_check(void *out, size_t len, const char *name)
175 {
176 	BOOL	ret = TRUE;
177 	int	i;
178 
179 	for (i = 0; i < tbsize; i++)
180 	{
181 		if ((ULONG_PTR)out < (ULONG_PTR)(altbl[i].aladr))
182 			continue;
183 		if ((ULONG_PTR)out < (ULONG_PTR)(altbl[i].aladr) + altbl[i].len)
184 		{
185 			if ((ULONG_PTR)out + len > (ULONG_PTR)(altbl[i].aladr) + altbl[i].len)
186 			{
187 				ret = FALSE;
188 				MYLOG(0, "%s:%s:out_check found memory buffer overrun %p(" FORMAT_SIZE_T ")>=%p(" FORMAT_SIZE_T ")\n", ALCERR, name, out, len, altbl[i].aladr, altbl[i].len);
189 			}
190 			break;
191 		}
192 	}
193 	return ret;
194 }
pgdebug_strcpy(char * out,const char * in)195 char *pgdebug_strcpy(char *out, const char *in)
196 {
197 	if (!out || !in)
198 	{
199 		MYLOG(0, "%s null pointer out=%p,in=%p\n", ALCERR, out, in);
200 		return NULL;
201 	}
202 	out_check(out, strlen(in) + 1, __FUNCTION__);
203 	return strcpy(out, in);
204 }
pgdebug_strncpy(char * out,const char * in,size_t len)205 char *pgdebug_strncpy(char *out, const char *in, size_t len)
206 {
207 	if (!out || !in)
208 	{
209 		MYLOG(0, "%s null pointer out=%p,in=%p\n", ALCERR, out, in);
210 		return NULL;
211 	}
212 	out_check(out, len, __FUNCTION__);
213 	return strncpy(out, in, len);
214 }
pgdebug_strncpy_null(char * out,const char * in,size_t len)215 char *pgdebug_strncpy_null(char *out, const char *in, size_t len)
216 {
217 	if (!out || !in)
218 	{
219 		MYLOG(0, "%s null pointer out=%p,in=%p\n", ALCERR, out, in);
220 		return NULL;
221 	}
222 	out_check(out, len, __FUNCTION__);
223 	strncpy_null(out, in, len);
224 	return out;
225 }
226 
pgdebug_memcpy(void * out,const void * in,size_t len)227 void *pgdebug_memcpy(void *out, const void *in, size_t len)
228 {
229 	if (!out || !in)
230 	{
231 		MYLOG(0, "%s null pointer out=%p,in=%p\n", ALCERR, out, in);
232 		return NULL;
233 	}
234 	out_check(out, len, __FUNCTION__);
235 	return memcpy(out, in, len);
236 }
237 
pgdebug_memset(void * out,int c,size_t len)238 void *pgdebug_memset(void *out, int c, size_t len)
239 {
240 	if (!out)
241 	{
242 		MYLOG(0, "%s null pointer out=%p\n", ALCERR, out);
243 		return NULL;
244 	}
245 	out_check(out, len, __FUNCTION__);
246 	return memset(out, c, len);
247 }
248 
debug_memory_check(void)249 void debug_memory_check(void)
250 {
251 	int i;
252 
253 	if (0 == tbsize)
254 	{
255 		MYLOG(0, "no memry leak found and max count allocated so far is %d\n", alsize);
256 		free(altbl);
257 		alsize = 0;
258 	}
259 	else
260 	{
261 		MYLOG(0, "%s:memory leak found check count=%d alloc=%d\n", ALCERR, tbsize, alsize);
262 		for (i = 0; i < tbsize; i++)
263 		{
264 			MYLOG(0, "%s:leak = %p(" FORMAT_SIZE_T ")\n", ALCERR, altbl[i].aladr, altbl[i].len);
265 		}
266 	}
267 }
268