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