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