xref: /PHP-5.5/ext/mysqlnd/mysqlnd_alloc.c (revision 73c1be26)
1 /*
2   +----------------------------------------------------------------------+
3   | PHP Version 5                                                        |
4   +----------------------------------------------------------------------+
5   | Copyright (c) 2006-2015 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_orig_filename "/unknown/unknown"
69 #define __zend_orig_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 	TRACE_ALLOC_ENTER(mysqlnd_emalloc_name);
85 
86 #if PHP_DEBUG
87 	{
88 		char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
89 		TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_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) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
98 #if PHP_DEBUG
99 		--*threshold;
100 	} else if (*threshold == 0) {
101 		ret = NULL;
102 	}
103 #endif
104 
105 	TRACE_ALLOC_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 	TRACE_ALLOC_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 	TRACE_ALLOC_ENTER(mysqlnd_pemalloc_name);
125 
126 #if PHP_DEBUG
127 	{
128 		char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
129 		TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
130 	}
131 #endif
132 
133 #if PHP_DEBUG
134 	/* -1 is also "true" */
135 	if (*threshold) {
136 #endif
137 		ret = (persistent) ? __zend_malloc(REAL_SIZE(size)) : _emalloc(REAL_SIZE(size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
138 #if PHP_DEBUG
139 		--*threshold;
140 	} else if (*threshold == 0) {
141 		ret = NULL;
142 	}
143 #endif
144 
145 	TRACE_ALLOC_INF_FMT("size=%lu ptr=%p persistent=%u", size, ret, persistent);
146 
147 	if (ret && collect_memory_statistics) {
148 		enum mysqlnd_collected_stats s1 = persistent? STAT_MEM_MALLOC_COUNT:STAT_MEM_EMALLOC_COUNT;
149 		enum mysqlnd_collected_stats s2 = persistent? STAT_MEM_MALLOC_AMOUNT:STAT_MEM_EMALLOC_AMOUNT;
150 		*(size_t *) ret = size;
151 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(s1, 1, s2, size);
152 	}
153 
154 	TRACE_ALLOC_RETURN(FAKE_PTR(ret));
155 }
156 /* }}} */
157 
158 
159 /* {{{ _mysqlnd_ecalloc */
_mysqlnd_ecalloc(unsigned int nmemb,size_t size MYSQLND_MEM_D)160 void * _mysqlnd_ecalloc(unsigned int nmemb, size_t size MYSQLND_MEM_D)
161 {
162 	void *ret;
163 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
164 #if PHP_DEBUG
165 	long * threshold = &MYSQLND_G(debug_ecalloc_fail_threshold);
166 #endif
167 	TRACE_ALLOC_ENTER(mysqlnd_ecalloc_name);
168 
169 #if PHP_DEBUG
170 	{
171 		char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
172 		TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
173 	}
174 #endif
175 	TRACE_ALLOC_INF_FMT("before: %lu", zend_memory_usage(FALSE TSRMLS_CC));
176 
177 #if PHP_DEBUG
178 	/* -1 is also "true" */
179 	if (*threshold) {
180 #endif
181 		ret = _ecalloc(nmemb, REAL_SIZE(size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
182 #if PHP_DEBUG
183 		--*threshold;
184 	} else if (*threshold == 0) {
185 		ret = NULL;
186 	}
187 #endif
188 
189 	TRACE_ALLOC_INF_FMT("after : %lu", zend_memory_usage(FALSE TSRMLS_CC));
190 	TRACE_ALLOC_INF_FMT("size=%lu ptr=%p", size, ret);
191 	if (ret && collect_memory_statistics) {
192 		*(size_t *) ret = size;
193 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_ECALLOC_COUNT, 1, STAT_MEM_ECALLOC_AMOUNT, size);
194 	}
195 	TRACE_ALLOC_RETURN(FAKE_PTR(ret));
196 }
197 /* }}} */
198 
199 
200 /* {{{ _mysqlnd_pecalloc */
_mysqlnd_pecalloc(unsigned int nmemb,size_t size,zend_bool persistent MYSQLND_MEM_D)201 void * _mysqlnd_pecalloc(unsigned int nmemb, size_t size, zend_bool persistent MYSQLND_MEM_D)
202 {
203 	void *ret;
204 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
205 #if PHP_DEBUG
206 	long * threshold = persistent? &MYSQLND_G(debug_calloc_fail_threshold):&MYSQLND_G(debug_ecalloc_fail_threshold);
207 #endif
208 	TRACE_ALLOC_ENTER(mysqlnd_pecalloc_name);
209 #if PHP_DEBUG
210 	{
211 		char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
212 		TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
213 	}
214 #endif
215 
216 #if PHP_DEBUG
217 	/* -1 is also "true" */
218 	if (*threshold) {
219 #endif
220 		ret = (persistent) ? __zend_calloc(nmemb, REAL_SIZE(size)) : _ecalloc(nmemb, REAL_SIZE(size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
221 #if PHP_DEBUG
222 		--*threshold;
223 	} else if (*threshold == 0) {
224 		ret = NULL;
225 	}
226 #endif
227 
228 	TRACE_ALLOC_INF_FMT("size=%lu ptr=%p", size, ret);
229 
230 	if (ret && collect_memory_statistics) {
231 		enum mysqlnd_collected_stats s1 = persistent? STAT_MEM_CALLOC_COUNT:STAT_MEM_ECALLOC_COUNT;
232 		enum mysqlnd_collected_stats s2 = persistent? STAT_MEM_CALLOC_AMOUNT:STAT_MEM_ECALLOC_AMOUNT;
233 		*(size_t *) ret = size;
234 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(s1, 1, s2, size);
235 	}
236 
237 	TRACE_ALLOC_RETURN(FAKE_PTR(ret));
238 }
239 /* }}} */
240 
241 
242 /* {{{ _mysqlnd_erealloc */
_mysqlnd_erealloc(void * ptr,size_t new_size MYSQLND_MEM_D)243 void * _mysqlnd_erealloc(void *ptr, size_t new_size MYSQLND_MEM_D)
244 {
245 	void *ret;
246 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
247 	size_t old_size = collect_memory_statistics && ptr? *(size_t *) (((char*)ptr) - sizeof(size_t)) : 0;
248 #if PHP_DEBUG
249 	long * threshold = &MYSQLND_G(debug_erealloc_fail_threshold);
250 #endif
251 	TRACE_ALLOC_ENTER(mysqlnd_erealloc_name);
252 
253 #if PHP_DEBUG
254 	{
255 		char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
256 		TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
257 	}
258 #endif
259 	TRACE_ALLOC_INF_FMT("ptr=%p old_size=%lu, new_size=%lu", ptr, old_size, new_size);
260 
261 #if PHP_DEBUG
262 	/* -1 is also "true" */
263 	if (*threshold) {
264 #endif
265 		ret = _erealloc(REAL_PTR(ptr), REAL_SIZE(new_size), 0 ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
266 #if PHP_DEBUG
267 		--*threshold;
268 	} else if (*threshold == 0) {
269 		ret = NULL;
270 	}
271 #endif
272 
273 	TRACE_ALLOC_INF_FMT("new_ptr=%p", (char*)ret);
274 	if (ret && collect_memory_statistics) {
275 		*(size_t *) ret = new_size;
276 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_EREALLOC_COUNT, 1, STAT_MEM_EREALLOC_AMOUNT, new_size);
277 	}
278 	TRACE_ALLOC_RETURN(FAKE_PTR(ret));
279 }
280 /* }}} */
281 
282 
283 /* {{{ _mysqlnd_perealloc */
_mysqlnd_perealloc(void * ptr,size_t new_size,zend_bool persistent MYSQLND_MEM_D)284 void * _mysqlnd_perealloc(void *ptr, size_t new_size, zend_bool persistent MYSQLND_MEM_D)
285 {
286 	void *ret;
287 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
288 	size_t old_size = collect_memory_statistics && ptr? *(size_t *) (((char*)ptr) - sizeof(size_t)) : 0;
289 #if PHP_DEBUG
290 	long * threshold = persistent? &MYSQLND_G(debug_realloc_fail_threshold):&MYSQLND_G(debug_erealloc_fail_threshold);
291 #endif
292 	TRACE_ALLOC_ENTER(mysqlnd_perealloc_name);
293 
294 #if PHP_DEBUG
295 	{
296 		char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
297 		TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
298 	}
299 #endif
300 	TRACE_ALLOC_INF_FMT("ptr=%p old_size=%lu new_size=%lu   persistent=%u", ptr, old_size, new_size, persistent);
301 
302 #if PHP_DEBUG
303 	/* -1 is also "true" */
304 	if (*threshold) {
305 #endif
306 		ret = perealloc(REAL_PTR(ptr), REAL_SIZE(new_size), persistent);
307 #if PHP_DEBUG
308 		--*threshold;
309 	} else if (*threshold == 0) {
310 		ret = NULL;
311 	}
312 #endif
313 
314 	TRACE_ALLOC_INF_FMT("new_ptr=%p", (char*)ret);
315 
316 	if (ret && collect_memory_statistics) {
317 		enum mysqlnd_collected_stats s1 = persistent? STAT_MEM_REALLOC_COUNT:STAT_MEM_EREALLOC_COUNT;
318 		enum mysqlnd_collected_stats s2 = persistent? STAT_MEM_REALLOC_AMOUNT:STAT_MEM_EREALLOC_AMOUNT;
319 		*(size_t *) ret = new_size;
320 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(s1, 1, s2, new_size);
321 	}
322 	TRACE_ALLOC_RETURN(FAKE_PTR(ret));
323 }
324 /* }}} */
325 
326 
327 /* {{{ _mysqlnd_efree */
_mysqlnd_efree(void * ptr MYSQLND_MEM_D)328 void _mysqlnd_efree(void *ptr MYSQLND_MEM_D)
329 {
330 	size_t free_amount = 0;
331 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
332 	TRACE_ALLOC_ENTER(mysqlnd_efree_name);
333 
334 #if PHP_DEBUG
335 	{
336 		char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
337 		TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
338 	}
339 #endif
340 	TRACE_ALLOC_INF_FMT("ptr=%p", ptr);
341 
342 	if (ptr) {
343 		if (collect_memory_statistics) {
344 			free_amount = *(size_t *)(((char*)ptr) - sizeof(size_t));
345 			TRACE_ALLOC_INF_FMT("ptr=%p size=%u", ((char*)ptr) - sizeof(size_t), (unsigned int) free_amount);
346 		}
347 		_efree(REAL_PTR(ptr) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
348 	}
349 
350 	if (collect_memory_statistics) {
351 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_EFREE_COUNT, 1, STAT_MEM_EFREE_AMOUNT, free_amount);
352 	}
353 	TRACE_ALLOC_VOID_RETURN;
354 }
355 /* }}} */
356 
357 
358 /* {{{ _mysqlnd_pefree */
_mysqlnd_pefree(void * ptr,zend_bool persistent MYSQLND_MEM_D)359 void _mysqlnd_pefree(void *ptr, zend_bool persistent MYSQLND_MEM_D)
360 {
361 	size_t free_amount = 0;
362 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
363 	TRACE_ALLOC_ENTER(mysqlnd_pefree_name);
364 
365 #if PHP_DEBUG
366 	{
367 		char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
368 		TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
369 	}
370 #endif
371 	TRACE_ALLOC_INF_FMT("ptr=%p persistent=%u", ptr, persistent);
372 
373 	if (ptr) {
374 		if (collect_memory_statistics) {
375 			free_amount = *(size_t *)(((char*)ptr) - sizeof(size_t));
376 			TRACE_ALLOC_INF_FMT("ptr=%p size=%u", ((char*)ptr) - sizeof(size_t), (unsigned int) free_amount);
377 		}
378 		(persistent) ? free(REAL_PTR(ptr)) : _efree(REAL_PTR(ptr) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
379 	}
380 
381 	if (collect_memory_statistics) {
382 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(persistent? STAT_MEM_FREE_COUNT:STAT_MEM_EFREE_COUNT, 1,
383 											  persistent? STAT_MEM_FREE_AMOUNT:STAT_MEM_EFREE_AMOUNT, free_amount);
384 	}
385 	TRACE_ALLOC_VOID_RETURN;
386 }
387 /* }}} */
388 
389 
390 /* {{{ _mysqlnd_malloc */
_mysqlnd_malloc(size_t size MYSQLND_MEM_D)391 void * _mysqlnd_malloc(size_t size MYSQLND_MEM_D)
392 {
393 	void *ret;
394 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
395 #if PHP_DEBUG
396 	long * threshold = &MYSQLND_G(debug_malloc_fail_threshold);
397 #endif
398 	TRACE_ALLOC_ENTER(mysqlnd_malloc_name);
399 
400 #if PHP_DEBUG
401 	{
402 		char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
403 		TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
404 	}
405 #endif
406 
407 #if PHP_DEBUG
408 	/* -1 is also "true" */
409 	if (*threshold) {
410 #endif
411 		ret = malloc(REAL_SIZE(size));
412 #if PHP_DEBUG
413 		--*threshold;
414 	} else if (*threshold == 0) {
415 		ret = NULL;
416 	}
417 #endif
418 
419 	TRACE_ALLOC_INF_FMT("size=%lu ptr=%p", size, ret);
420 	if (ret && collect_memory_statistics) {
421 		*(size_t *) ret = size;
422 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_MALLOC_COUNT, 1, STAT_MEM_MALLOC_AMOUNT, size);
423 	}
424 	TRACE_ALLOC_RETURN(FAKE_PTR(ret));
425 }
426 /* }}} */
427 
428 
429 /* {{{ _mysqlnd_calloc */
_mysqlnd_calloc(unsigned int nmemb,size_t size MYSQLND_MEM_D)430 void * _mysqlnd_calloc(unsigned int nmemb, size_t size MYSQLND_MEM_D)
431 {
432 	void *ret;
433 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
434 #if PHP_DEBUG
435 	long * threshold = &MYSQLND_G(debug_calloc_fail_threshold);
436 #endif
437 	TRACE_ALLOC_ENTER(mysqlnd_calloc_name);
438 
439 #if PHP_DEBUG
440 	{
441 		char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
442 		TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
443 	}
444 #endif
445 
446 #if PHP_DEBUG
447 	/* -1 is also "true" */
448 	if (*threshold) {
449 #endif
450 		ret = calloc(nmemb, REAL_SIZE(size));
451 #if PHP_DEBUG
452 		--*threshold;
453 	} else if (*threshold == 0) {
454 		ret = NULL;
455 	}
456 #endif
457 
458 	TRACE_ALLOC_INF_FMT("size=%lu ptr=%p", size, ret);
459 	if (ret && collect_memory_statistics) {
460 		*(size_t *) ret = size;
461 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_CALLOC_COUNT, 1, STAT_MEM_CALLOC_AMOUNT, size);
462 	}
463 	TRACE_ALLOC_RETURN(FAKE_PTR(ret));
464 }
465 /* }}} */
466 
467 
468 /* {{{ _mysqlnd_realloc */
_mysqlnd_realloc(void * ptr,size_t new_size MYSQLND_MEM_D)469 void * _mysqlnd_realloc(void *ptr, size_t new_size MYSQLND_MEM_D)
470 {
471 	void *ret;
472 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
473 #if PHP_DEBUG
474 	long * threshold = &MYSQLND_G(debug_realloc_fail_threshold);
475 #endif
476 	TRACE_ALLOC_ENTER(mysqlnd_realloc_name);
477 
478 #if PHP_DEBUG
479 	{
480 		char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
481 		TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
482 	}
483 #endif
484 	TRACE_ALLOC_INF_FMT("ptr=%p new_size=%lu ", new_size, ptr);
485 	TRACE_ALLOC_INF_FMT("before: %lu", zend_memory_usage(TRUE TSRMLS_CC));
486 
487 #if PHP_DEBUG
488 	/* -1 is also "true" */
489 	if (*threshold) {
490 #endif
491 		ret = realloc(REAL_PTR(ptr), REAL_SIZE(new_size));
492 #if PHP_DEBUG
493 		--*threshold;
494 	} else if (*threshold == 0) {
495 		ret = NULL;
496 	}
497 #endif
498 
499 	TRACE_ALLOC_INF_FMT("new_ptr=%p", (char*)ret);
500 
501 	if (ret && collect_memory_statistics) {
502 		*(size_t *) ret = new_size;
503 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_REALLOC_COUNT, 1, STAT_MEM_REALLOC_AMOUNT, new_size);
504 	}
505 	TRACE_ALLOC_RETURN(FAKE_PTR(ret));
506 }
507 /* }}} */
508 
509 
510 /* {{{ _mysqlnd_free */
_mysqlnd_free(void * ptr MYSQLND_MEM_D)511 void _mysqlnd_free(void *ptr MYSQLND_MEM_D)
512 {
513 	size_t free_amount = 0;
514 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
515 	TRACE_ALLOC_ENTER(mysqlnd_free_name);
516 
517 #if PHP_DEBUG
518 	{
519 		char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
520 		TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
521 	}
522 #endif
523 	TRACE_ALLOC_INF_FMT("ptr=%p", ptr);
524 
525 	if (ptr) {
526 		if (collect_memory_statistics) {
527 			free_amount = *(size_t *)(((char*)ptr) - sizeof(size_t));
528 			TRACE_ALLOC_INF_FMT("ptr=%p size=%u", ((char*)ptr) - sizeof(size_t), (unsigned int) free_amount);
529 		}
530 		free(REAL_PTR(ptr));
531 	}
532 
533 	if (collect_memory_statistics) {
534 		MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_FREE_COUNT, 1, STAT_MEM_FREE_AMOUNT, free_amount);
535 	}
536 	TRACE_ALLOC_VOID_RETURN;
537 }
538 /* }}} */
539 
540 #define SMART_STR_START_SIZE 2048
541 #define SMART_STR_PREALLOC 512
542 #include "ext/standard/php_smart_str.h"
543 
544 
545 /* {{{ _mysqlnd_pestrndup */
_mysqlnd_pestrndup(const char * const ptr,size_t length,zend_bool persistent MYSQLND_MEM_D)546 char * _mysqlnd_pestrndup(const char * const ptr, size_t length, zend_bool persistent MYSQLND_MEM_D)
547 {
548 	char * ret;
549 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
550 	TRACE_ALLOC_ENTER(mysqlnd_pestrndup_name);
551 
552 #if PHP_DEBUG
553 	{
554 		char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
555 		TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
556 	}
557 #endif
558 	TRACE_ALLOC_INF_FMT("ptr=%p", ptr);
559 
560 	ret = (persistent) ? __zend_malloc(REAL_SIZE(length + 1)) : _emalloc(REAL_SIZE(length + 1) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
561 	{
562 		size_t l = length;
563 		char * p = (char *) ptr;
564 		char * dest = (char *) FAKE_PTR(ret);
565 		while (*p && l--) {
566 			*dest++ = *p++;
567 		}
568 		*dest = '\0';
569 	}
570 
571 	if (collect_memory_statistics) {
572 		*(size_t *) ret = length;
573 		MYSQLND_INC_GLOBAL_STATISTIC(persistent? STAT_MEM_STRNDUP_COUNT : STAT_MEM_ESTRNDUP_COUNT);
574 	}
575 
576 	TRACE_ALLOC_RETURN(FAKE_PTR(ret));
577 }
578 /* }}} */
579 
580 
581 /* {{{ _mysqlnd_pestrdup */
_mysqlnd_pestrdup(const char * const ptr,zend_bool persistent MYSQLND_MEM_D)582 char * _mysqlnd_pestrdup(const char * const ptr, zend_bool persistent MYSQLND_MEM_D)
583 {
584 	char * ret;
585 	smart_str tmp_str = {0, 0, 0};
586 	const char * p = ptr;
587 	zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
588 	TRACE_ALLOC_ENTER(mysqlnd_pestrdup_name);
589 #if PHP_DEBUG
590 	{
591 		char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
592 		TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
593 	}
594 #endif
595 	TRACE_ALLOC_INF_FMT("ptr=%p", ptr);
596 	do {
597 		smart_str_appendc(&tmp_str, *p);
598 	} while (*p++);
599 
600 	ret = (persistent) ? __zend_malloc(tmp_str.len + sizeof(size_t)) : _emalloc(REAL_SIZE(tmp_str.len + sizeof(size_t)) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
601 	memcpy(FAKE_PTR(ret), tmp_str.c, tmp_str.len);
602 
603 	if (ret && collect_memory_statistics) {
604 		*(size_t *) ret = tmp_str.len;
605 		MYSQLND_INC_GLOBAL_STATISTIC(persistent? STAT_MEM_STRDUP_COUNT : STAT_MEM_ESTRDUP_COUNT);
606 	}
607 	smart_str_free(&tmp_str);
608 
609 	TRACE_ALLOC_RETURN(FAKE_PTR(ret));
610 }
611 /* }}} */
612 
613 
614 /* {{{ _mysqlnd_sprintf */
_mysqlnd_sprintf(char ** pbuf,size_t max_len,const char * format,...)615 PHPAPI int _mysqlnd_sprintf(char ** pbuf, size_t max_len, const char *format, ...)
616 {
617 	int len;
618 	va_list ap;
619 	va_start(ap, format);
620 	len = vspprintf(pbuf, max_len, format, ap);
621 	va_end(ap);
622 	return len;
623 }
624 /* }}} */
625 
626 
627 /* {{{ _mysqlnd_sprintf_free */
_mysqlnd_sprintf_free(char * p)628 PHPAPI void _mysqlnd_sprintf_free(char * p)
629 {
630 	efree(p);
631 }
632 /* }}} */
633 
634 /* {{{ _mysqlnd_vsprintf */
_mysqlnd_vsprintf(char ** pbuf,size_t max_len,const char * format,va_list ap)635 PHPAPI int _mysqlnd_vsprintf(char ** pbuf, size_t max_len, const char * format, va_list ap)
636 {
637 	return vspprintf(pbuf, max_len, format, ap);
638 }
639 /* }}} */
640 
641 
642 #define MYSQLND_DEBUG_MEMORY 1
643 
644 #if MYSQLND_DEBUG_MEMORY == 0
645 
646 /* {{{ mysqlnd_zend_mm_emalloc */
mysqlnd_zend_mm_emalloc(size_t size MYSQLND_MEM_D)647 static void * mysqlnd_zend_mm_emalloc(size_t size MYSQLND_MEM_D)
648 {
649 	return emalloc(size);
650 }
651 /* }}} */
652 
653 
654 /* {{{ mysqlnd_zend_mm_pemalloc */
mysqlnd_zend_mm_pemalloc(size_t size,zend_bool persistent MYSQLND_MEM_D)655 static void * mysqlnd_zend_mm_pemalloc(size_t size, zend_bool persistent MYSQLND_MEM_D)
656 {
657 	return pemalloc(size, persistent);
658 }
659 /* }}} */
660 
661 
662 /* {{{ mysqlnd_zend_mm_ecalloc */
mysqlnd_zend_mm_ecalloc(unsigned int nmemb,size_t size MYSQLND_MEM_D)663 static void * mysqlnd_zend_mm_ecalloc(unsigned int nmemb, size_t size MYSQLND_MEM_D)
664 {
665 	return ecalloc(nmemb, size);
666 }
667 /* }}} */
668 
669 
670 /* {{{ mysqlnd_zend_mm_pecalloc */
mysqlnd_zend_mm_pecalloc(unsigned int nmemb,size_t size,zend_bool persistent MYSQLND_MEM_D)671 static void * mysqlnd_zend_mm_pecalloc(unsigned int nmemb, size_t size, zend_bool persistent MYSQLND_MEM_D)
672 {
673 	return pecalloc(nmemb, size, persistent);
674 }
675 /* }}} */
676 
677 
678 /* {{{ mysqlnd_zend_mm_erealloc */
mysqlnd_zend_mm_erealloc(void * ptr,size_t new_size MYSQLND_MEM_D)679 static void * mysqlnd_zend_mm_erealloc(void *ptr, size_t new_size MYSQLND_MEM_D)
680 {
681 	return erealloc(ptr, new_size);
682 }
683 /* }}} */
684 
685 
686 /* {{{ mysqlnd_zend_mm_perealloc */
mysqlnd_zend_mm_perealloc(void * ptr,size_t new_size,zend_bool persistent MYSQLND_MEM_D)687 static void * mysqlnd_zend_mm_perealloc(void *ptr, size_t new_size, zend_bool persistent MYSQLND_MEM_D)
688 {
689 	return perealloc(ptr, new_size, persistent);
690 }
691 /* }}} */
692 
693 
694 /* {{{ mysqlnd_zend_mm_efree */
mysqlnd_zend_mm_efree(void * ptr MYSQLND_MEM_D)695 static void mysqlnd_zend_mm_efree(void * ptr MYSQLND_MEM_D)
696 {
697 	efree(ptr);
698 }
699 /* }}} */
700 
701 
702 /* {{{ mysqlnd_zend_mm_pefree */
mysqlnd_zend_mm_pefree(void * ptr,zend_bool persistent MYSQLND_MEM_D)703 static void mysqlnd_zend_mm_pefree(void * ptr, zend_bool persistent MYSQLND_MEM_D)
704 {
705 	pefree(ptr, persistent);
706 }
707 /* }}} */
708 
709 
710 /* {{{ mysqlnd_zend_mm_malloc */
mysqlnd_zend_mm_malloc(size_t size MYSQLND_MEM_D)711 static void * mysqlnd_zend_mm_malloc(size_t size MYSQLND_MEM_D)
712 {
713 	return malloc(size);
714 }
715 /* }}} */
716 
717 
718 /* {{{ mysqlnd_zend_mm_calloc */
mysqlnd_zend_mm_calloc(unsigned int nmemb,size_t size MYSQLND_MEM_D)719 static void * mysqlnd_zend_mm_calloc(unsigned int nmemb, size_t size MYSQLND_MEM_D)
720 {
721 	return calloc(nmemb, size);
722 }
723 /* }}} */
724 
725 
726 /* {{{ mysqlnd_zend_mm_realloc */
mysqlnd_zend_mm_realloc(void * ptr,size_t new_size MYSQLND_MEM_D)727 static void * mysqlnd_zend_mm_realloc(void * ptr, size_t new_size MYSQLND_MEM_D)
728 {
729 	return realloc(ptr, new_size);
730 }
731 /* }}} */
732 
733 
734 /* {{{ mysqlnd_zend_mm_free */
mysqlnd_zend_mm_free(void * ptr MYSQLND_MEM_D)735 static void mysqlnd_zend_mm_free(void * ptr MYSQLND_MEM_D)
736 {
737 	free(ptr);
738 }
739 /* }}} */
740 
741 
742 /* {{{ mysqlnd_zend_mm_pestrndup */
mysqlnd_zend_mm_pestrndup(const char * const ptr,size_t length,zend_bool persistent MYSQLND_MEM_D)743 static char * mysqlnd_zend_mm_pestrndup(const char * const ptr, size_t length, zend_bool persistent MYSQLND_MEM_D)
744 {
745 	return pestrndup(ptr, length, persistent);
746 }
747 /* }}} */
748 
749 
750 /* {{{ mysqlnd_zend_mm_pestrdup */
mysqlnd_zend_mm_pestrdup(const char * const ptr,zend_bool persistent MYSQLND_MEM_D)751 static char * mysqlnd_zend_mm_pestrdup(const char * const ptr, zend_bool persistent MYSQLND_MEM_D)
752 {
753 	return pestrdup(ptr, persistent);
754 }
755 /* }}} */
756 
757 #endif
758 
759 
760 PHPAPI struct st_mysqlnd_allocator_methods mysqlnd_allocator =
761 {
762 #if MYSQLND_DEBUG_MEMORY
763 	_mysqlnd_emalloc,
764 	_mysqlnd_pemalloc,
765 	_mysqlnd_ecalloc,
766 	_mysqlnd_pecalloc,
767 	_mysqlnd_erealloc,
768 	_mysqlnd_perealloc,
769 	_mysqlnd_efree,
770 	_mysqlnd_pefree,
771 	_mysqlnd_malloc,
772 	_mysqlnd_calloc,
773 	_mysqlnd_realloc,
774 	_mysqlnd_free,
775 	_mysqlnd_pestrndup,
776 	_mysqlnd_pestrdup,
777 	_mysqlnd_sprintf,
778 	_mysqlnd_vsprintf,
779 	_mysqlnd_sprintf_free
780 #else
781 	mysqlnd_zend_mm_emalloc,
782 	mysqlnd_zend_mm_pemalloc,
783 	mysqlnd_zend_mm_ecalloc,
784 	mysqlnd_zend_mm_pecalloc,
785 	mysqlnd_zend_mm_erealloc,
786 	mysqlnd_zend_mm_perealloc,
787 	mysqlnd_zend_mm_efree,
788 	mysqlnd_zend_mm_pefree,
789 	mysqlnd_zend_mm_malloc,
790 	mysqlnd_zend_mm_calloc,
791 	mysqlnd_zend_mm_realloc,
792 	mysqlnd_zend_mm_free,
793 	mysqlnd_zend_mm_pestrndup,
794 	mysqlnd_zend_mm_pestrdup
795 	sprintf,
796 	mysqlnd_zend_mm_efree,
797 #endif
798 };
799 
800 
801 /*
802  * Local variables:
803  * tab-width: 4
804  * c-basic-offset: 4
805  * End:
806  * vim600: noet sw=4 ts=4 fdm=marker
807  * vim<600: noet sw=4 ts=4
808  */
809