xref: /PHP-5.4/ext/mysqlnd/mysqlnd_alloc.c (revision c0d060f5)
1 /*
2   +----------------------------------------------------------------------+
3   | PHP Version 5                                                        |
4   +----------------------------------------------------------------------+
5   | Copyright (c) 2006-2014 The PHP Group                                |
6   +----------------------------------------------------------------------+
7   | This source file is subject to version 3.01 of the PHP license,      |
8   | that is bundled with this package in the file LICENSE, and is        |
9   | available through the world-wide-web at the following url:           |
10   | http://www.php.net/license/3_01.txt                                  |
11   | If you did not receive a copy of the PHP license and are unable to   |
12   | obtain it through the world-wide-web, please send a note to          |
13   | license@php.net so we can mail you a copy immediately.               |
14   +----------------------------------------------------------------------+
15   | Authors: Georg Richter <georg@mysql.com>                             |
16   |          Andrey Hristov <andrey@mysql.com>                           |
17   |          Ulf Wendel <uwendel@mysql.com>                              |
18   +----------------------------------------------------------------------+
19 */
20 
21 /* $Id: mysqlnd_debug.c 309303 2011-03-16 12:42:59Z andrey $ */
22 #include "php.h"
23 #include "mysqlnd.h"
24 #include "mysqlnd_priv.h"
25 #include "mysqlnd_debug.h"
26 #include "mysqlnd_wireprotocol.h"
27 #include "mysqlnd_statistics.h"
28 
29 
30 static const char mysqlnd_emalloc_name[]	= "_mysqlnd_emalloc";
31 static const char mysqlnd_pemalloc_name[]	= "_mysqlnd_pemalloc";
32 static const char mysqlnd_ecalloc_name[]	= "_mysqlnd_ecalloc";
33 static const char mysqlnd_pecalloc_name[]	= "_mysqlnd_pecalloc";
34 static const char mysqlnd_erealloc_name[]	= "_mysqlnd_erealloc";
35 static const char mysqlnd_perealloc_name[]	= "_mysqlnd_perealloc";
36 static const char mysqlnd_efree_name[]		= "_mysqlnd_efree";
37 static const char mysqlnd_pefree_name[]		= "_mysqlnd_pefree";
38 static const char mysqlnd_malloc_name[]		= "_mysqlnd_malloc";
39 static const char mysqlnd_calloc_name[]		= "_mysqlnd_calloc";
40 static const char mysqlnd_realloc_name[]	= "_mysqlnd_realloc";
41 static const char mysqlnd_free_name[]		= "_mysqlnd_free";
42 static const char mysqlnd_pestrndup_name[]	= "_mysqlnd_pestrndup";
43 static const char mysqlnd_pestrdup_name[]	= "_mysqlnd_pestrdup";
44 
45 PHPAPI const char * mysqlnd_debug_std_no_trace_funcs[] =
46 {
47 	mysqlnd_emalloc_name,
48 	mysqlnd_ecalloc_name,
49 	mysqlnd_efree_name,
50 	mysqlnd_erealloc_name,
51 	mysqlnd_pemalloc_name,
52 	mysqlnd_pecalloc_name,
53 	mysqlnd_pefree_name,
54 	mysqlnd_perealloc_name,
55 	mysqlnd_malloc_name,
56 	mysqlnd_calloc_name,
57 	mysqlnd_realloc_name,
58 	mysqlnd_free_name,
59 	mysqlnd_pestrndup_name,
60 	mysqlnd_read_header_name,
61 	mysqlnd_read_body_name,
62 	NULL /* must be always last */
63 };
64 
65 
66 #if ZEND_DEBUG
67 #else
68 #define __zend_filename "/unknown/unknown"
69 #define __zend_lineno   0
70 #endif
71 
72 #define REAL_SIZE(s) (collect_memory_statistics? (s) + sizeof(size_t) : (s))
73 #define REAL_PTR(p) (collect_memory_statistics && (p)? (((char *)(p)) - sizeof(size_t)) : (p))
74 #define FAKE_PTR(p) (collect_memory_statistics && (p)? (((char *)(p)) + sizeof(size_t)) : (p))
75 
76 /* {{{ _mysqlnd_emalloc */
_mysqlnd_emalloc(size_t size MYSQLND_MEM_D)77 void * _mysqlnd_emalloc(size_t size MYSQLND_MEM_D)
78 {
79 	void *ret;
80 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
81 #if PHP_DEBUG
82 	long * threshold = &MYSQLND_G(debug_emalloc_fail_threshold);
83 #endif
84 	DBG_ENTER(mysqlnd_emalloc_name);
85 
86 #if PHP_DEBUG
87 	{
88 		char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
89 		DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
90 	}
91 #endif
92 
93 #if PHP_DEBUG
94 	/* -1 is also "true" */
95 	if (*threshold) {
96 #endif
97 		ret = emalloc(REAL_SIZE(size));
98 #if PHP_DEBUG
99 		--*threshold;
100 	} else if (*threshold == 0) {
101 		ret = NULL;
102 	}
103 #endif
104 
105 	DBG_INF_FMT("size=%lu ptr=%p", size, ret);
106 
107 	if (ret && collect_memory_statistics) {
108 		*(size_t *) ret = size;
109 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_EMALLOC_COUNT, 1, STAT_MEM_EMALLOC_AMOUNT, size);
110 	}
111 	DBG_RETURN(FAKE_PTR(ret));
112 }
113 /* }}} */
114 
115 
116 /* {{{ _mysqlnd_pemalloc */
_mysqlnd_pemalloc(size_t size,zend_bool persistent MYSQLND_MEM_D)117 void * _mysqlnd_pemalloc(size_t size, zend_bool persistent MYSQLND_MEM_D)
118 {
119 	void *ret;
120 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
121 #if PHP_DEBUG
122 	long * threshold = persistent? &MYSQLND_G(debug_malloc_fail_threshold):&MYSQLND_G(debug_emalloc_fail_threshold);
123 #endif
124 	DBG_ENTER(mysqlnd_pemalloc_name);
125 #if PHP_DEBUG
126 	{
127 		char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
128 		DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
129 	}
130 #endif
131 
132 #if PHP_DEBUG
133 	/* -1 is also "true" */
134 	if (*threshold) {
135 #endif
136 		ret = pemalloc(REAL_SIZE(size), persistent);
137 #if PHP_DEBUG
138 		--*threshold;
139 	} else if (*threshold == 0) {
140 		ret = NULL;
141 	}
142 #endif
143 
144 	DBG_INF_FMT("size=%lu ptr=%p persistent=%u", size, ret, persistent);
145 
146 	if (ret && collect_memory_statistics) {
147 		enum mysqlnd_collected_stats s1 = persistent? STAT_MEM_MALLOC_COUNT:STAT_MEM_EMALLOC_COUNT;
148 		enum mysqlnd_collected_stats s2 = persistent? STAT_MEM_MALLOC_AMOUNT:STAT_MEM_EMALLOC_AMOUNT;
149 		*(size_t *) ret = size;
150 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(s1, 1, s2, size);
151 	}
152 
153 	DBG_RETURN(FAKE_PTR(ret));
154 }
155 /* }}} */
156 
157 
158 /* {{{ _mysqlnd_ecalloc */
_mysqlnd_ecalloc(unsigned int nmemb,size_t size MYSQLND_MEM_D)159 void * _mysqlnd_ecalloc(unsigned int nmemb, size_t size MYSQLND_MEM_D)
160 {
161 	void *ret;
162 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
163 #if PHP_DEBUG
164 	long * threshold = &MYSQLND_G(debug_ecalloc_fail_threshold);
165 #endif
166 	DBG_ENTER(mysqlnd_ecalloc_name);
167 #if PHP_DEBUG
168 	{
169 		char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
170 		DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
171 	}
172 #endif
173 	DBG_INF_FMT("before: %lu", zend_memory_usage(FALSE TSRMLS_CC));
174 
175 #if PHP_DEBUG
176 	/* -1 is also "true" */
177 	if (*threshold) {
178 #endif
179 		ret = ecalloc(nmemb, REAL_SIZE(size));
180 #if PHP_DEBUG
181 		--*threshold;
182 	} else if (*threshold == 0) {
183 		ret = NULL;
184 	}
185 #endif
186 
187 	DBG_INF_FMT("after : %lu", zend_memory_usage(FALSE TSRMLS_CC));
188 	DBG_INF_FMT("size=%lu ptr=%p", size, ret);
189 	if (ret && collect_memory_statistics) {
190 		*(size_t *) ret = size;
191 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_ECALLOC_COUNT, 1, STAT_MEM_ECALLOC_AMOUNT, size);
192 	}
193 	DBG_RETURN(FAKE_PTR(ret));
194 }
195 /* }}} */
196 
197 
198 /* {{{ _mysqlnd_pecalloc */
_mysqlnd_pecalloc(unsigned int nmemb,size_t size,zend_bool persistent MYSQLND_MEM_D)199 void * _mysqlnd_pecalloc(unsigned int nmemb, size_t size, zend_bool persistent MYSQLND_MEM_D)
200 {
201 	void *ret;
202 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
203 #if PHP_DEBUG
204 	long * threshold = persistent? &MYSQLND_G(debug_calloc_fail_threshold):&MYSQLND_G(debug_ecalloc_fail_threshold);
205 #endif
206 	DBG_ENTER(mysqlnd_pecalloc_name);
207 #if PHP_DEBUG
208 	{
209 		char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
210 		DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
211 	}
212 #endif
213 
214 #if PHP_DEBUG
215 	/* -1 is also "true" */
216 	if (*threshold) {
217 #endif
218 		ret = pecalloc(nmemb, REAL_SIZE(size), persistent);
219 #if PHP_DEBUG
220 		--*threshold;
221 	} else if (*threshold == 0) {
222 		ret = NULL;
223 	}
224 #endif
225 
226 	DBG_INF_FMT("size=%lu ptr=%p", size, ret);
227 
228 	if (ret && collect_memory_statistics) {
229 		enum mysqlnd_collected_stats s1 = persistent? STAT_MEM_CALLOC_COUNT:STAT_MEM_ECALLOC_COUNT;
230 		enum mysqlnd_collected_stats s2 = persistent? STAT_MEM_CALLOC_AMOUNT:STAT_MEM_ECALLOC_AMOUNT;
231 		*(size_t *) ret = size;
232 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(s1, 1, s2, size);
233 	}
234 
235 	DBG_RETURN(FAKE_PTR(ret));
236 }
237 /* }}} */
238 
239 
240 /* {{{ _mysqlnd_erealloc */
_mysqlnd_erealloc(void * ptr,size_t new_size MYSQLND_MEM_D)241 void * _mysqlnd_erealloc(void *ptr, size_t new_size MYSQLND_MEM_D)
242 {
243 	void *ret;
244 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
245 	size_t old_size = collect_memory_statistics && ptr? *(size_t *) (((char*)ptr) - sizeof(size_t)) : 0;
246 #if PHP_DEBUG
247 	long * threshold = &MYSQLND_G(debug_erealloc_fail_threshold);
248 #endif
249 	DBG_ENTER(mysqlnd_erealloc_name);
250 #if PHP_DEBUG
251 	{
252 		char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
253 		DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
254 	}
255 #endif
256 	DBG_INF_FMT("ptr=%p old_size=%lu, new_size=%lu", ptr, old_size, new_size);
257 
258 #if PHP_DEBUG
259 	/* -1 is also "true" */
260 	if (*threshold) {
261 #endif
262 		ret = erealloc(REAL_PTR(ptr), REAL_SIZE(new_size));
263 #if PHP_DEBUG
264 		--*threshold;
265 	} else if (*threshold == 0) {
266 		ret = NULL;
267 	}
268 #endif
269 
270 	DBG_INF_FMT("new_ptr=%p", (char*)ret);
271 	if (ret && collect_memory_statistics) {
272 		*(size_t *) ret = new_size;
273 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_EREALLOC_COUNT, 1, STAT_MEM_EREALLOC_AMOUNT, new_size);
274 	}
275 	DBG_RETURN(FAKE_PTR(ret));
276 }
277 /* }}} */
278 
279 
280 /* {{{ _mysqlnd_perealloc */
_mysqlnd_perealloc(void * ptr,size_t new_size,zend_bool persistent MYSQLND_MEM_D)281 void * _mysqlnd_perealloc(void *ptr, size_t new_size, zend_bool persistent MYSQLND_MEM_D)
282 {
283 	void *ret;
284 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
285 	size_t old_size = collect_memory_statistics && ptr? *(size_t *) (((char*)ptr) - sizeof(size_t)) : 0;
286 #if PHP_DEBUG
287 	long * threshold = persistent? &MYSQLND_G(debug_realloc_fail_threshold):&MYSQLND_G(debug_erealloc_fail_threshold);
288 #endif
289 	DBG_ENTER(mysqlnd_perealloc_name);
290 #if PHP_DEBUG
291 	{
292 		char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
293 		DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
294 	}
295 #endif
296 	DBG_INF_FMT("ptr=%p old_size=%lu new_size=%lu persistent=%u", ptr, old_size, new_size, persistent);
297 
298 #if PHP_DEBUG
299 	/* -1 is also "true" */
300 	if (*threshold) {
301 #endif
302 		ret = perealloc(REAL_PTR(ptr), REAL_SIZE(new_size), persistent);
303 #if PHP_DEBUG
304 		--*threshold;
305 	} else if (*threshold == 0) {
306 		ret = NULL;
307 	}
308 #endif
309 
310 	DBG_INF_FMT("new_ptr=%p", (char*)ret);
311 
312 	if (ret && collect_memory_statistics) {
313 		enum mysqlnd_collected_stats s1 = persistent? STAT_MEM_REALLOC_COUNT:STAT_MEM_EREALLOC_COUNT;
314 		enum mysqlnd_collected_stats s2 = persistent? STAT_MEM_REALLOC_AMOUNT:STAT_MEM_EREALLOC_AMOUNT;
315 		*(size_t *) ret = new_size;
316 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(s1, 1, s2, new_size);
317 	}
318 	DBG_RETURN(FAKE_PTR(ret));
319 }
320 /* }}} */
321 
322 
323 /* {{{ _mysqlnd_efree */
_mysqlnd_efree(void * ptr MYSQLND_MEM_D)324 void _mysqlnd_efree(void *ptr MYSQLND_MEM_D)
325 {
326 	size_t free_amount = 0;
327 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
328 	DBG_ENTER(mysqlnd_efree_name);
329 #if PHP_DEBUG
330 	{
331 		char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
332 		DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
333 	}
334 #endif
335 	DBG_INF_FMT("ptr=%p", ptr);
336 
337 	if (ptr) {
338 		if (collect_memory_statistics) {
339 			free_amount = *(size_t *)(((char*)ptr) - sizeof(size_t));
340 			DBG_INF_FMT("ptr=%p size=%u", ((char*)ptr) - sizeof(size_t), (unsigned int) free_amount);
341 		}
342 		efree(REAL_PTR(ptr));
343 	}
344 
345 	if (collect_memory_statistics) {
346 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_EFREE_COUNT, 1, STAT_MEM_EFREE_AMOUNT, free_amount);
347 	}
348 	DBG_VOID_RETURN;
349 }
350 /* }}} */
351 
352 
353 /* {{{ _mysqlnd_pefree */
_mysqlnd_pefree(void * ptr,zend_bool persistent MYSQLND_MEM_D)354 void _mysqlnd_pefree(void *ptr, zend_bool persistent MYSQLND_MEM_D)
355 {
356 	size_t free_amount = 0;
357 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
358 	DBG_ENTER(mysqlnd_pefree_name);
359 #if PHP_DEBUG
360 	{
361 		char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
362 		DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
363 	}
364 #endif
365 	DBG_INF_FMT("ptr=%p persistent=%u", ptr, persistent);
366 
367 	if (ptr) {
368 		if (collect_memory_statistics) {
369 			free_amount = *(size_t *)(((char*)ptr) - sizeof(size_t));
370 			DBG_INF_FMT("ptr=%p size=%u", ((char*)ptr) - sizeof(size_t), (unsigned int) free_amount);
371 		}
372 		pefree(REAL_PTR(ptr), persistent);
373 	}
374 
375 	if (collect_memory_statistics) {
376 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(persistent? STAT_MEM_FREE_COUNT:STAT_MEM_EFREE_COUNT, 1,
377 											  persistent? STAT_MEM_FREE_AMOUNT:STAT_MEM_EFREE_AMOUNT, free_amount);
378 	}
379 	DBG_VOID_RETURN;
380 }
381 
382 
383 /* {{{ _mysqlnd_malloc */
_mysqlnd_malloc(size_t size MYSQLND_MEM_D)384 void * _mysqlnd_malloc(size_t size MYSQLND_MEM_D)
385 {
386 	void *ret;
387 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
388 #if PHP_DEBUG
389 	long * threshold = &MYSQLND_G(debug_malloc_fail_threshold);
390 #endif
391 	DBG_ENTER(mysqlnd_malloc_name);
392 #if PHP_DEBUG
393 	{
394 		char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
395 		DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
396 	}
397 #endif
398 
399 #if PHP_DEBUG
400 	/* -1 is also "true" */
401 	if (*threshold) {
402 #endif
403 		ret = malloc(REAL_SIZE(size));
404 #if PHP_DEBUG
405 		--*threshold;
406 	} else if (*threshold == 0) {
407 		ret = NULL;
408 	}
409 #endif
410 
411 	DBG_INF_FMT("size=%lu ptr=%p", size, ret);
412 	if (ret && collect_memory_statistics) {
413 		*(size_t *) ret = size;
414 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_MALLOC_COUNT, 1, STAT_MEM_MALLOC_AMOUNT, size);
415 	}
416 	DBG_RETURN(FAKE_PTR(ret));
417 }
418 /* }}} */
419 
420 
421 /* {{{ _mysqlnd_calloc */
_mysqlnd_calloc(unsigned int nmemb,size_t size MYSQLND_MEM_D)422 void * _mysqlnd_calloc(unsigned int nmemb, size_t size MYSQLND_MEM_D)
423 {
424 	void *ret;
425 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
426 #if PHP_DEBUG
427 	long * threshold = &MYSQLND_G(debug_calloc_fail_threshold);
428 #endif
429 	DBG_ENTER(mysqlnd_calloc_name);
430 #if PHP_DEBUG
431 	{
432 		char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
433 		DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
434 	}
435 #endif
436 
437 #if PHP_DEBUG
438 	/* -1 is also "true" */
439 	if (*threshold) {
440 #endif
441 		ret = calloc(nmemb, REAL_SIZE(size));
442 #if PHP_DEBUG
443 		--*threshold;
444 	} else if (*threshold == 0) {
445 		ret = NULL;
446 	}
447 #endif
448 
449 	DBG_INF_FMT("size=%lu ptr=%p", size, ret);
450 	if (ret && collect_memory_statistics) {
451 		*(size_t *) ret = size;
452 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_CALLOC_COUNT, 1, STAT_MEM_CALLOC_AMOUNT, size);
453 	}
454 	DBG_RETURN(FAKE_PTR(ret));
455 }
456 /* }}} */
457 
458 
459 /* {{{ _mysqlnd_realloc */
_mysqlnd_realloc(void * ptr,size_t new_size MYSQLND_MEM_D)460 void * _mysqlnd_realloc(void *ptr, size_t new_size MYSQLND_MEM_D)
461 {
462 	void *ret;
463 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
464 #if PHP_DEBUG
465 	long * threshold = &MYSQLND_G(debug_realloc_fail_threshold);
466 #endif
467 	DBG_ENTER(mysqlnd_realloc_name);
468 #if PHP_DEBUG
469 	{
470 		char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
471 		DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
472 	}
473 #endif
474 	DBG_INF_FMT("ptr=%p new_size=%lu ", new_size, ptr);
475 	DBG_INF_FMT("before: %lu", zend_memory_usage(TRUE TSRMLS_CC));
476 
477 #if PHP_DEBUG
478 	/* -1 is also "true" */
479 	if (*threshold) {
480 #endif
481 		ret = realloc(REAL_PTR(ptr), REAL_SIZE(new_size));
482 #if PHP_DEBUG
483 		--*threshold;
484 	} else if (*threshold == 0) {
485 		ret = NULL;
486 	}
487 #endif
488 
489 	DBG_INF_FMT("new_ptr=%p", (char*)ret);
490 
491 	if (ret && collect_memory_statistics) {
492 		*(size_t *) ret = new_size;
493 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_REALLOC_COUNT, 1, STAT_MEM_REALLOC_AMOUNT, new_size);
494 	}
495 	DBG_RETURN(FAKE_PTR(ret));
496 }
497 /* }}} */
498 
499 
500 /* {{{ _mysqlnd_free */
_mysqlnd_free(void * ptr MYSQLND_MEM_D)501 void _mysqlnd_free(void *ptr MYSQLND_MEM_D)
502 {
503 	size_t free_amount = 0;
504 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
505 	DBG_ENTER(mysqlnd_free_name);
506 #if PHP_DEBUG
507 	{
508 		char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
509 		DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
510 	}
511 #endif
512 	DBG_INF_FMT("ptr=%p", ptr);
513 
514 	if (ptr) {
515 		if (collect_memory_statistics) {
516 			free_amount = *(size_t *)(((char*)ptr) - sizeof(size_t));
517 			DBG_INF_FMT("ptr=%p size=%u", ((char*)ptr) - sizeof(size_t), (unsigned int) free_amount);
518 		}
519 		free(REAL_PTR(ptr));
520 	}
521 
522 	if (collect_memory_statistics) {
523 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_FREE_COUNT, 1, STAT_MEM_FREE_AMOUNT, free_amount);
524 	}
525 	DBG_VOID_RETURN;
526 }
527 /* }}} */
528 
529 #define SMART_STR_START_SIZE 2048
530 #define SMART_STR_PREALLOC 512
531 #include "ext/standard/php_smart_str.h"
532 
533 
534 /* {{{ _mysqlnd_pestrndup */
_mysqlnd_pestrndup(const char * const ptr,size_t length,zend_bool persistent MYSQLND_MEM_D)535 char * _mysqlnd_pestrndup(const char * const ptr, size_t length, zend_bool persistent MYSQLND_MEM_D)
536 {
537 	char * ret;
538 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
539 	DBG_ENTER(mysqlnd_pestrndup_name);
540 #if PHP_DEBUG
541 	{
542 		char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
543 		DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
544 	}
545 #endif
546 	DBG_INF_FMT("ptr=%p", ptr);
547 
548 	ret = pemalloc(REAL_SIZE(length) + 1, persistent);
549 	{
550 		size_t l = length;
551 		char * p = (char *) ptr;
552 		char * dest = (char *) FAKE_PTR(ret);
553 		while (*p && l--) {
554 			*dest++ = *p++;
555 		}
556 		*dest = '\0';
557 	}
558 
559 	if (collect_memory_statistics) {
560 		*(size_t *) ret = length;
561 		MYSQLND_INC_GLOBAL_STATISTIC(persistent? STAT_MEM_STRNDUP_COUNT : STAT_MEM_ESTRNDUP_COUNT);
562 	}
563 
564 	DBG_RETURN(FAKE_PTR(ret));
565 }
566 /* }}} */
567 
568 
569 /* {{{ _mysqlnd_pestrdup */
_mysqlnd_pestrdup(const char * const ptr,zend_bool persistent MYSQLND_MEM_D)570 char * _mysqlnd_pestrdup(const char * const ptr, zend_bool persistent MYSQLND_MEM_D)
571 {
572 	char * ret;
573 	smart_str tmp_str = {0, 0, 0};
574 	const char * p = ptr;
575 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
576 	DBG_ENTER(mysqlnd_pestrdup_name);
577 #if PHP_DEBUG
578 	{
579 		char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
580 		DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
581 	}
582 #endif
583 	DBG_INF_FMT("ptr=%p", ptr);
584 	do {
585 		smart_str_appendc(&tmp_str, *p);
586 	} while (*p++);
587 
588 	ret = pemalloc(tmp_str.len + sizeof(size_t), persistent);
589 	memcpy(FAKE_PTR(ret), tmp_str.c, tmp_str.len);
590 
591 	if (ret && collect_memory_statistics) {
592 		*(size_t *) ret = tmp_str.len;
593 		MYSQLND_INC_GLOBAL_STATISTIC(persistent? STAT_MEM_STRDUP_COUNT : STAT_MEM_ESTRDUP_COUNT);
594 	}
595 	smart_str_free(&tmp_str);
596 
597 	DBG_RETURN(FAKE_PTR(ret));
598 }
599 /* }}} */
600 
601 
602 /* {{{ _mysqlnd_sprintf */
_mysqlnd_sprintf(char ** pbuf,size_t max_len,const char * format,...)603 PHPAPI int _mysqlnd_sprintf(char ** pbuf, size_t max_len, const char *format, ...)
604 {
605 	int len;
606 	va_list ap;
607 	va_start(ap, format);
608 	len = vspprintf(pbuf, max_len, format, ap);
609 	va_end(ap);
610 	return len;
611 }
612 /* }}} */
613 
614 
615 /* {{{ _mysqlnd_sprintf_free */
_mysqlnd_sprintf_free(char * p)616 PHPAPI void _mysqlnd_sprintf_free(char * p)
617 {
618 	efree(p);
619 }
620 /* }}} */
621 
622 
_mysqlnd_vsprintf(char ** pbuf,size_t max_len,const char * format,va_list ap)623 PHPAPI int _mysqlnd_vsprintf(char ** pbuf, size_t max_len, const char * format, va_list ap)
624 {
625 	return vspprintf(pbuf, max_len, format, ap);
626 }
627 /* }}} */
628 
629 
630 #define MYSQLND_DEBUG_MEMORY 1
631 
632 #if MYSQLND_DEBUG_MEMORY == 0
633 
634 /* {{{ mysqlnd_zend_mm_emalloc */
mysqlnd_zend_mm_emalloc(size_t size MYSQLND_MEM_D)635 static void * mysqlnd_zend_mm_emalloc(size_t size MYSQLND_MEM_D)
636 {
637 	return emalloc(size);
638 }
639 /* }}} */
640 
641 
642 /* {{{ mysqlnd_zend_mm_pemalloc */
mysqlnd_zend_mm_pemalloc(size_t size,zend_bool persistent MYSQLND_MEM_D)643 static void * mysqlnd_zend_mm_pemalloc(size_t size, zend_bool persistent MYSQLND_MEM_D)
644 {
645 	return pemalloc(size, persistent);
646 }
647 /* }}} */
648 
649 
650 /* {{{ mysqlnd_zend_mm_ecalloc */
mysqlnd_zend_mm_ecalloc(unsigned int nmemb,size_t size MYSQLND_MEM_D)651 static void * mysqlnd_zend_mm_ecalloc(unsigned int nmemb, size_t size MYSQLND_MEM_D)
652 {
653 	return ecalloc(nmemb, size);
654 }
655 /* }}} */
656 
657 
658 /* {{{ mysqlnd_zend_mm_pecalloc */
mysqlnd_zend_mm_pecalloc(unsigned int nmemb,size_t size,zend_bool persistent MYSQLND_MEM_D)659 static void * mysqlnd_zend_mm_pecalloc(unsigned int nmemb, size_t size, zend_bool persistent MYSQLND_MEM_D)
660 {
661 	return pecalloc(nmemb, size, persistent);
662 }
663 /* }}} */
664 
665 
666 /* {{{ mysqlnd_zend_mm_erealloc */
mysqlnd_zend_mm_erealloc(void * ptr,size_t new_size MYSQLND_MEM_D)667 static void * mysqlnd_zend_mm_erealloc(void *ptr, size_t new_size MYSQLND_MEM_D)
668 {
669 	return erealloc(ptr, new_size);
670 }
671 /* }}} */
672 
673 
674 /* {{{ mysqlnd_zend_mm_perealloc */
mysqlnd_zend_mm_perealloc(void * ptr,size_t new_size,zend_bool persistent MYSQLND_MEM_D)675 static void * mysqlnd_zend_mm_perealloc(void *ptr, size_t new_size, zend_bool persistent MYSQLND_MEM_D)
676 {
677 	return perealloc(ptr, new_size, persistent);
678 }
679 /* }}} */
680 
681 
682 /* {{{ mysqlnd_zend_mm_efree */
mysqlnd_zend_mm_efree(void * ptr MYSQLND_MEM_D)683 static void mysqlnd_zend_mm_efree(void * ptr MYSQLND_MEM_D)
684 {
685 	efree(ptr);
686 }
687 /* }}} */
688 
689 
690 /* {{{ mysqlnd_zend_mm_pefree */
mysqlnd_zend_mm_pefree(void * ptr,zend_bool persistent MYSQLND_MEM_D)691 static void mysqlnd_zend_mm_pefree(void * ptr, zend_bool persistent MYSQLND_MEM_D)
692 {
693 	pefree(ptr, persistent);
694 }
695 /* }}} */
696 
697 
698 /* {{{ mysqlnd_zend_mm_malloc */
mysqlnd_zend_mm_malloc(size_t size MYSQLND_MEM_D)699 static void * mysqlnd_zend_mm_malloc(size_t size MYSQLND_MEM_D)
700 {
701 	return malloc(size);
702 }
703 /* }}} */
704 
705 
706 /* {{{ mysqlnd_zend_mm_calloc */
mysqlnd_zend_mm_calloc(unsigned int nmemb,size_t size MYSQLND_MEM_D)707 static void * mysqlnd_zend_mm_calloc(unsigned int nmemb, size_t size MYSQLND_MEM_D)
708 {
709 	return calloc(nmemb, size);
710 }
711 /* }}} */
712 
713 
714 /* {{{ mysqlnd_zend_mm_realloc */
mysqlnd_zend_mm_realloc(void * ptr,size_t new_size MYSQLND_MEM_D)715 static void * mysqlnd_zend_mm_realloc(void * ptr, size_t new_size MYSQLND_MEM_D)
716 {
717 	return realloc(ptr, new_size);
718 }
719 /* }}} */
720 
721 
722 /* {{{ mysqlnd_zend_mm_free */
mysqlnd_zend_mm_free(void * ptr MYSQLND_MEM_D)723 static void mysqlnd_zend_mm_free(void * ptr MYSQLND_MEM_D)
724 {
725 	free(ptr);
726 }
727 /* }}} */
728 
729 
730 /* {{{ mysqlnd_zend_mm_pestrndup */
mysqlnd_zend_mm_pestrndup(const char * const ptr,size_t length,zend_bool persistent MYSQLND_MEM_D)731 static char * mysqlnd_zend_mm_pestrndup(const char * const ptr, size_t length, zend_bool persistent MYSQLND_MEM_D)
732 {
733 	return pestrndup(ptr, length, persistent);
734 }
735 /* }}} */
736 
737 
738 /* {{{ mysqlnd_zend_mm_pestrdup */
mysqlnd_zend_mm_pestrdup(const char * const ptr,zend_bool persistent MYSQLND_MEM_D)739 static char * mysqlnd_zend_mm_pestrdup(const char * const ptr, zend_bool persistent MYSQLND_MEM_D)
740 {
741 	return pestrdup(ptr, persistent);
742 }
743 /* }}} */
744 
745 #endif
746 
747 
748 PHPAPI struct st_mysqlnd_allocator_methods mysqlnd_allocator =
749 {
750 #if MYSQLND_DEBUG_MEMORY
751 	_mysqlnd_emalloc,
752 	_mysqlnd_pemalloc,
753 	_mysqlnd_ecalloc,
754 	_mysqlnd_pecalloc,
755 	_mysqlnd_erealloc,
756 	_mysqlnd_perealloc,
757 	_mysqlnd_efree,
758 	_mysqlnd_pefree,
759 	_mysqlnd_malloc,
760 	_mysqlnd_calloc,
761 	_mysqlnd_realloc,
762 	_mysqlnd_free,
763 	_mysqlnd_pestrndup,
764 	_mysqlnd_pestrdup,
765 	_mysqlnd_sprintf,
766 	_mysqlnd_vsprintf,
767 	_mysqlnd_sprintf_free
768 #else
769 	mysqlnd_zend_mm_emalloc,
770 	mysqlnd_zend_mm_pemalloc,
771 	mysqlnd_zend_mm_ecalloc,
772 	mysqlnd_zend_mm_pecalloc,
773 	mysqlnd_zend_mm_erealloc,
774 	mysqlnd_zend_mm_perealloc,
775 	mysqlnd_zend_mm_efree,
776 	mysqlnd_zend_mm_pefree,
777 	mysqlnd_zend_mm_malloc,
778 	mysqlnd_zend_mm_calloc,
779 	mysqlnd_zend_mm_realloc,
780 	mysqlnd_zend_mm_free,
781 	mysqlnd_zend_mm_pestrndup,
782 	mysqlnd_zend_mm_pestrdup
783 	sprintf,
784 	mysqlnd_zend_mm_efree,
785 #endif
786 };
787 
788 
789 /*
790  * Local variables:
791  * tab-width: 4
792  * c-basic-offset: 4
793  * End:
794  * vim600: noet sw=4 ts=4 fdm=marker
795  * vim<600: noet sw=4 ts=4
796  */
797