From 8c14436f73ca5b55d2f55ab01a488a2d9ffd4e1c Mon Sep 17 00:00:00 2001 From: Andrey Hristov Date: Fri, 18 Mar 2011 11:58:46 +0000 Subject: [PATCH] split mysqlnd_debug.c in 3 files --- ext/mysqlnd/config.w32 | 2 + ext/mysqlnd/config9.m4 | 2 +- ext/mysqlnd/mysqlnd_alloc.c | 674 ++++++++++++++++++++++ ext/mysqlnd/mysqlnd_alloc.h | 92 +++ ext/mysqlnd/mysqlnd_bt.c | 483 ++++++++++++++++ ext/mysqlnd/mysqlnd_debug.c | 1091 +---------------------------------- ext/mysqlnd/mysqlnd_debug.h | 63 +- 7 files changed, 1255 insertions(+), 1152 deletions(-) create mode 100644 ext/mysqlnd/mysqlnd_alloc.c create mode 100644 ext/mysqlnd/mysqlnd_alloc.h create mode 100644 ext/mysqlnd/mysqlnd_bt.c diff --git a/ext/mysqlnd/config.w32 b/ext/mysqlnd/config.w32 index 49da1ccafd..1c1ddec45c 100644 --- a/ext/mysqlnd/config.w32 +++ b/ext/mysqlnd/config.w32 @@ -7,8 +7,10 @@ if (PHP_MYSQLND != "no") { if (CHECK_LIB("ws2_32.lib", "mysqlnd")) { mysqlnd_source = "mysqlnd.c " + + "mysqlnd_alloc.c" + "mysqlnd_auth.c " + "mysqlnd_block_alloc.c " + + "mysqlnd_bt.c" + "mysqlnd_charset.c " + "mysqlnd_debug.c " + "mysqlnd_loaddata.c " + diff --git a/ext/mysqlnd/config9.m4 b/ext/mysqlnd/config9.m4 index 9104a85889..46cdca74e7 100644 --- a/ext/mysqlnd/config9.m4 +++ b/ext/mysqlnd/config9.m4 @@ -14,7 +14,7 @@ fi dnl If some extension uses mysqlnd it will get compiled in PHP core if test "$PHP_MYSQLND_ENABLED" = "yes"; then - mysqlnd_sources="mysqlnd.c mysqlnd_charset.c mysqlnd_wireprotocol.c \ + mysqlnd_sources="mysqlnd.c mysqlnd_alloc.c mysqlnd_bt.c mysqlnd_charset.c mysqlnd_wireprotocol.c \ mysqlnd_ps.c mysqlnd_loaddata.c mysqlnd_net.c \ mysqlnd_ps_codec.c mysqlnd_statistics.c mysqlnd_auth.c \ mysqlnd_result.c mysqlnd_result_meta.c mysqlnd_debug.c\ diff --git a/ext/mysqlnd/mysqlnd_alloc.c b/ext/mysqlnd/mysqlnd_alloc.c new file mode 100644 index 0000000000..808f3ae41e --- /dev/null +++ b/ext/mysqlnd/mysqlnd_alloc.c @@ -0,0 +1,674 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 2006-2011 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Georg Richter | + | Andrey Hristov | + | Ulf Wendel | + +----------------------------------------------------------------------+ +*/ + +/* $Id: mysqlnd_debug.c 309303 2011-03-16 12:42:59Z andrey $ */ +#include "php.h" +#include "mysqlnd.h" +#include "mysqlnd_priv.h" +#include "mysqlnd_debug.h" +#include "mysqlnd_wireprotocol.h" +#include "mysqlnd_statistics.h" + + +static const char mysqlnd_emalloc_name[] = "_mysqlnd_emalloc"; +static const char mysqlnd_pemalloc_name[] = "_mysqlnd_pemalloc"; +static const char mysqlnd_ecalloc_name[] = "_mysqlnd_ecalloc"; +static const char mysqlnd_pecalloc_name[] = "_mysqlnd_pecalloc"; +static const char mysqlnd_erealloc_name[] = "_mysqlnd_erealloc"; +static const char mysqlnd_perealloc_name[] = "_mysqlnd_perealloc"; +static const char mysqlnd_efree_name[] = "_mysqlnd_efree"; +static const char mysqlnd_pefree_name[] = "_mysqlnd_pefree"; +static const char mysqlnd_malloc_name[] = "_mysqlnd_malloc"; +static const char mysqlnd_calloc_name[] = "_mysqlnd_calloc"; +static const char mysqlnd_realloc_name[] = "_mysqlnd_realloc"; +static const char mysqlnd_free_name[] = "_mysqlnd_free"; +static const char mysqlnd_pestrndup_name[] = "_mysqlnd_pestrndup"; +static const char mysqlnd_pestrdup_name[] = "_mysqlnd_pestrdup"; + +const char * mysqlnd_debug_std_no_trace_funcs[] = +{ + mysqlnd_emalloc_name, + mysqlnd_ecalloc_name, + mysqlnd_efree_name, + mysqlnd_erealloc_name, + mysqlnd_pemalloc_name, + mysqlnd_pecalloc_name, + mysqlnd_pefree_name, + mysqlnd_perealloc_name, + mysqlnd_malloc_name, + mysqlnd_calloc_name, + mysqlnd_realloc_name, + mysqlnd_free_name, + mysqlnd_pestrndup_name, + mysqlnd_read_header_name, + mysqlnd_read_body_name, + NULL /* must be always last */ +}; + + +#if ZEND_DEBUG +#else +#define __zend_filename "/unknown/unknown" +#define __zend_lineno 0 +#endif + +#define REAL_SIZE(s) (collect_memory_statistics? (s) + sizeof(size_t) : (s)) +#define REAL_PTR(p) (collect_memory_statistics && (p)? (((char *)(p)) - sizeof(size_t)) : (p)) +#define FAKE_PTR(p) (collect_memory_statistics && (p)? (((char *)(p)) + sizeof(size_t)) : (p)) + +/* {{{ _mysqlnd_emalloc */ +void * _mysqlnd_emalloc(size_t size MYSQLND_MEM_D) +{ + void *ret; + zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); + long * threshold = &MYSQLND_G(debug_emalloc_fail_threshold); + DBG_ENTER(mysqlnd_emalloc_name); + + DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); + +#if PHP_DEBUG + /* -1 is also "true" */ + if (*threshold) { +#endif + ret = emalloc(REAL_SIZE(size)); +#if PHP_DEBUG + --*threshold; + } else if (*threshold == 0) { + ret = NULL; + } +#endif + + DBG_INF_FMT("size=%lu ptr=%p", size, ret); + + if (ret && collect_memory_statistics) { + *(size_t *) ret = size; + MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_EMALLOC_COUNT, 1, STAT_MEM_EMALLOC_AMOUNT, size); + } + DBG_RETURN(FAKE_PTR(ret)); +} +/* }}} */ + + +/* {{{ _mysqlnd_pemalloc */ +void * _mysqlnd_pemalloc(size_t size, zend_bool persistent MYSQLND_MEM_D) +{ + void *ret; + zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); + long * threshold = persistent? &MYSQLND_G(debug_malloc_fail_threshold):&MYSQLND_G(debug_emalloc_fail_threshold); + DBG_ENTER(mysqlnd_pemalloc_name); + DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); + +#if PHP_DEBUG + /* -1 is also "true" */ + if (*threshold) { +#endif + ret = pemalloc(REAL_SIZE(size), persistent); +#if PHP_DEBUG + --*threshold; + } else if (*threshold == 0) { + ret = NULL; + } +#endif + + DBG_INF_FMT("size=%lu ptr=%p persistent=%u", size, ret, persistent); + + if (ret && collect_memory_statistics) { + enum mysqlnd_collected_stats s1 = persistent? STAT_MEM_MALLOC_COUNT:STAT_MEM_EMALLOC_COUNT; + enum mysqlnd_collected_stats s2 = persistent? STAT_MEM_MALLOC_AMOUNT:STAT_MEM_EMALLOC_AMOUNT; + *(size_t *) ret = size; + MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(s1, 1, s2, size); + } + + DBG_RETURN(FAKE_PTR(ret)); +} +/* }}} */ + + +/* {{{ _mysqlnd_ecalloc */ +void * _mysqlnd_ecalloc(unsigned int nmemb, size_t size MYSQLND_MEM_D) +{ + void *ret; + zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); + long * threshold = &MYSQLND_G(debug_ecalloc_fail_threshold); + DBG_ENTER(mysqlnd_ecalloc_name); + DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); + DBG_INF_FMT("before: %lu", zend_memory_usage(FALSE TSRMLS_CC)); + +#if PHP_DEBUG + /* -1 is also "true" */ + if (*threshold) { +#endif + ret = ecalloc(nmemb, REAL_SIZE(size)); +#if PHP_DEBUG + --*threshold; + } else if (*threshold == 0) { + ret = NULL; + } +#endif + + DBG_INF_FMT("after : %lu", zend_memory_usage(FALSE TSRMLS_CC)); + DBG_INF_FMT("size=%lu ptr=%p", size, ret); + if (ret && collect_memory_statistics) { + *(size_t *) ret = size; + MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_ECALLOC_COUNT, 1, STAT_MEM_ECALLOC_AMOUNT, size); + } + DBG_RETURN(FAKE_PTR(ret)); +} +/* }}} */ + + +/* {{{ _mysqlnd_pecalloc */ +void * _mysqlnd_pecalloc(unsigned int nmemb, size_t size, zend_bool persistent MYSQLND_MEM_D) +{ + void *ret; + zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); + long * threshold = persistent? &MYSQLND_G(debug_calloc_fail_threshold):&MYSQLND_G(debug_ecalloc_fail_threshold); + DBG_ENTER(mysqlnd_pecalloc_name); + DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); + +#if PHP_DEBUG + /* -1 is also "true" */ + if (*threshold) { +#endif + ret = pecalloc(nmemb, REAL_SIZE(size), persistent); +#if PHP_DEBUG + --*threshold; + } else if (*threshold == 0) { + ret = NULL; + } +#endif + + DBG_INF_FMT("size=%lu ptr=%p", size, ret); + + if (ret && collect_memory_statistics) { + enum mysqlnd_collected_stats s1 = persistent? STAT_MEM_CALLOC_COUNT:STAT_MEM_ECALLOC_COUNT; + enum mysqlnd_collected_stats s2 = persistent? STAT_MEM_CALLOC_AMOUNT:STAT_MEM_ECALLOC_AMOUNT; + *(size_t *) ret = size; + MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(s1, 1, s2, size); + } + + DBG_RETURN(FAKE_PTR(ret)); +} +/* }}} */ + + +/* {{{ _mysqlnd_erealloc */ +void * _mysqlnd_erealloc(void *ptr, size_t new_size MYSQLND_MEM_D) +{ + void *ret; + zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); + size_t old_size = collect_memory_statistics && ptr? *(size_t *) (((char*)ptr) - sizeof(size_t)) : 0; + long * threshold = &MYSQLND_G(debug_erealloc_fail_threshold); + DBG_ENTER(mysqlnd_erealloc_name); + DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); + DBG_INF_FMT("ptr=%p old_size=%lu, new_size=%lu", ptr, old_size, new_size); + +#if PHP_DEBUG + /* -1 is also "true" */ + if (*threshold) { +#endif + ret = erealloc(REAL_PTR(ptr), REAL_SIZE(new_size)); +#if PHP_DEBUG + --*threshold; + } else if (*threshold == 0) { + ret = NULL; + } +#endif + + DBG_INF_FMT("new_ptr=%p", (char*)ret); + if (ret && collect_memory_statistics) { + *(size_t *) ret = new_size; + MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_EREALLOC_COUNT, 1, STAT_MEM_EREALLOC_AMOUNT, new_size); + } + DBG_RETURN(FAKE_PTR(ret)); +} +/* }}} */ + + +/* {{{ _mysqlnd_perealloc */ +void * _mysqlnd_perealloc(void *ptr, size_t new_size, zend_bool persistent MYSQLND_MEM_D) +{ + void *ret; + zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); + size_t old_size = collect_memory_statistics && ptr? *(size_t *) (((char*)ptr) - sizeof(size_t)) : 0; + long * threshold = persistent? &MYSQLND_G(debug_realloc_fail_threshold):&MYSQLND_G(debug_erealloc_fail_threshold); + DBG_ENTER(mysqlnd_perealloc_name); + DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); + DBG_INF_FMT("ptr=%p old_size=%lu new_size=%lu persistent=%u", ptr, old_size, new_size, persistent); + +#if PHP_DEBUG + /* -1 is also "true" */ + if (*threshold) { +#endif + ret = perealloc(REAL_PTR(ptr), REAL_SIZE(new_size), persistent); +#if PHP_DEBUG + --*threshold; + } else if (*threshold == 0) { + ret = NULL; + } +#endif + + DBG_INF_FMT("new_ptr=%p", (char*)ret); + + if (ret && collect_memory_statistics) { + enum mysqlnd_collected_stats s1 = persistent? STAT_MEM_REALLOC_COUNT:STAT_MEM_EREALLOC_COUNT; + enum mysqlnd_collected_stats s2 = persistent? STAT_MEM_REALLOC_AMOUNT:STAT_MEM_EREALLOC_AMOUNT; + *(size_t *) ret = new_size; + MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(s1, 1, s2, new_size); + } + DBG_RETURN(FAKE_PTR(ret)); +} +/* }}} */ + + +/* {{{ _mysqlnd_efree */ +void _mysqlnd_efree(void *ptr MYSQLND_MEM_D) +{ + size_t free_amount = 0; + zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); + DBG_ENTER(mysqlnd_efree_name); + DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); + DBG_INF_FMT("ptr=%p", ptr); + + if (ptr) { + if (collect_memory_statistics) { + free_amount = *(size_t *)(((char*)ptr) - sizeof(size_t)); + DBG_INF_FMT("ptr=%p size=%u", ((char*)ptr) - sizeof(size_t), (unsigned int) free_amount); + } + efree(REAL_PTR(ptr)); + } + + if (collect_memory_statistics) { + MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_EFREE_COUNT, 1, STAT_MEM_EFREE_AMOUNT, free_amount); + } + DBG_VOID_RETURN; +} +/* }}} */ + + +/* {{{ _mysqlnd_pefree */ +void _mysqlnd_pefree(void *ptr, zend_bool persistent MYSQLND_MEM_D) +{ + size_t free_amount = 0; + zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); + DBG_ENTER(mysqlnd_pefree_name); + DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); + DBG_INF_FMT("ptr=%p persistent=%u", ptr, persistent); + + if (ptr) { + if (collect_memory_statistics) { + free_amount = *(size_t *)(((char*)ptr) - sizeof(size_t)); + DBG_INF_FMT("ptr=%p size=%u", ((char*)ptr) - sizeof(size_t), (unsigned int) free_amount); + } + pefree(REAL_PTR(ptr), persistent); + } + + if (collect_memory_statistics) { + MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(persistent? STAT_MEM_FREE_COUNT:STAT_MEM_EFREE_COUNT, 1, + persistent? STAT_MEM_FREE_AMOUNT:STAT_MEM_EFREE_AMOUNT, free_amount); + } + DBG_VOID_RETURN; +} + + +/* {{{ _mysqlnd_malloc */ +void * _mysqlnd_malloc(size_t size MYSQLND_MEM_D) +{ + void *ret; + zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); + long * threshold = &MYSQLND_G(debug_malloc_fail_threshold); + DBG_ENTER(mysqlnd_malloc_name); + DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); + +#if PHP_DEBUG + /* -1 is also "true" */ + if (*threshold) { +#endif + ret = malloc(REAL_SIZE(size)); +#if PHP_DEBUG + --*threshold; + } else if (*threshold == 0) { + ret = NULL; + } +#endif + + DBG_INF_FMT("size=%lu ptr=%p", size, ret); + if (ret && collect_memory_statistics) { + *(size_t *) ret = size; + MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_MALLOC_COUNT, 1, STAT_MEM_MALLOC_AMOUNT, size); + } + DBG_RETURN(FAKE_PTR(ret)); +} +/* }}} */ + + +/* {{{ _mysqlnd_calloc */ +void * _mysqlnd_calloc(unsigned int nmemb, size_t size MYSQLND_MEM_D) +{ + void *ret; + zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); + long * threshold = &MYSQLND_G(debug_calloc_fail_threshold); + DBG_ENTER(mysqlnd_calloc_name); + DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); + +#if PHP_DEBUG + /* -1 is also "true" */ + if (*threshold) { +#endif + ret = calloc(nmemb, REAL_SIZE(size)); +#if PHP_DEBUG + --*threshold; + } else if (*threshold == 0) { + ret = NULL; + } +#endif + + DBG_INF_FMT("size=%lu ptr=%p", size, ret); + if (ret && collect_memory_statistics) { + *(size_t *) ret = size; + MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_CALLOC_COUNT, 1, STAT_MEM_CALLOC_AMOUNT, size); + } + DBG_RETURN(FAKE_PTR(ret)); +} +/* }}} */ + + +/* {{{ _mysqlnd_realloc */ +void * _mysqlnd_realloc(void *ptr, size_t new_size MYSQLND_MEM_D) +{ + void *ret; + zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); + long * threshold = &MYSQLND_G(debug_realloc_fail_threshold); + DBG_ENTER(mysqlnd_realloc_name); + DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); + DBG_INF_FMT("ptr=%p new_size=%lu ", new_size, ptr); + DBG_INF_FMT("before: %lu", zend_memory_usage(TRUE TSRMLS_CC)); + +#if PHP_DEBUG + /* -1 is also "true" */ + if (*threshold) { +#endif + ret = realloc(REAL_PTR(ptr), REAL_SIZE(new_size)); +#if PHP_DEBUG + --*threshold; + } else if (*threshold == 0) { + ret = NULL; + } +#endif + + DBG_INF_FMT("new_ptr=%p", (char*)ret); + + if (ret && collect_memory_statistics) { + *(size_t *) ret = new_size; + MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_REALLOC_COUNT, 1, STAT_MEM_REALLOC_AMOUNT, new_size); + } + DBG_RETURN(FAKE_PTR(ret)); +} +/* }}} */ + + +/* {{{ _mysqlnd_free */ +void _mysqlnd_free(void *ptr MYSQLND_MEM_D) +{ + size_t free_amount = 0; + zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); + DBG_ENTER(mysqlnd_free_name); + DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); + DBG_INF_FMT("ptr=%p", ptr); + + if (ptr) { + if (collect_memory_statistics) { + free_amount = *(size_t *)(((char*)ptr) - sizeof(size_t)); + DBG_INF_FMT("ptr=%p size=%u", ((char*)ptr) - sizeof(size_t), (unsigned int) free_amount); + } + free(REAL_PTR(ptr)); + } + + if (collect_memory_statistics) { + MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_FREE_COUNT, 1, STAT_MEM_FREE_AMOUNT, free_amount); + } + DBG_VOID_RETURN; +} +/* }}} */ + +#define SMART_STR_START_SIZE 2048 +#define SMART_STR_PREALLOC 512 +#include "ext/standard/php_smart_str.h" + + +/* {{{ _mysqlnd_pestrndup */ +char * _mysqlnd_pestrndup(const char * const ptr, size_t length, zend_bool persistent MYSQLND_MEM_D) +{ + char * ret; + zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); + DBG_ENTER(mysqlnd_pestrndup_name); + DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); + DBG_INF_FMT("ptr=%p", ptr); + + ret = pemalloc(REAL_SIZE(length) + 1, persistent); + { + size_t l = length; + char * p = (char *) ptr; + char * dest = (char *) FAKE_PTR(ret); + while (*p && l--) { + *dest++ = *p++; + } + *dest = '\0'; + } + + if (collect_memory_statistics) { + *(size_t *) ret = length; + MYSQLND_INC_GLOBAL_STATISTIC(persistent? STAT_MEM_STRNDUP_COUNT : STAT_MEM_ESTRNDUP_COUNT); + } + + DBG_RETURN(FAKE_PTR(ret)); +} +/* }}} */ + + +/* {{{ _mysqlnd_pestrdup */ +char * _mysqlnd_pestrdup(const char * const ptr, zend_bool persistent MYSQLND_MEM_D) +{ + char * ret; + smart_str tmp_str = {0, 0, 0}; + const char * p = ptr; + zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); + DBG_ENTER(mysqlnd_pestrdup_name); + DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); + DBG_INF_FMT("ptr=%p", ptr); + do { + smart_str_appendc(&tmp_str, *p); + } while (*p++); + + ret = pemalloc(tmp_str.len + sizeof(size_t), persistent); + memcpy(FAKE_PTR(ret), tmp_str.c, tmp_str.len); + + if (ret && collect_memory_statistics) { + *(size_t *) ret = tmp_str.len; + MYSQLND_INC_GLOBAL_STATISTIC(persistent? STAT_MEM_STRDUP_COUNT : STAT_MEM_ESTRDUP_COUNT); + } + smart_str_free(&tmp_str); + + DBG_RETURN(FAKE_PTR(ret)); +} +/* }}} */ + +#define MYSQLND_DEBUG_MEMORY 1 + +#if MYSQLND_DEBUG_MEMORY == 0 + +/* {{{ mysqlnd_zend_mm_emalloc */ +static void * mysqlnd_zend_mm_emalloc(size_t size MYSQLND_MEM_D) +{ + return emalloc(size); +} +/* }}} */ + + +/* {{{ mysqlnd_zend_mm_pemalloc */ +static void * mysqlnd_zend_mm_pemalloc(size_t size, zend_bool persistent MYSQLND_MEM_D) +{ + return pemalloc(size, persistent); +} +/* }}} */ + + +/* {{{ mysqlnd_zend_mm_ecalloc */ +static void * mysqlnd_zend_mm_ecalloc(unsigned int nmemb, size_t size MYSQLND_MEM_D) +{ + return ecalloc(nmemb, size); +} +/* }}} */ + + +/* {{{ mysqlnd_zend_mm_pecalloc */ +static void * mysqlnd_zend_mm_pecalloc(unsigned int nmemb, size_t size, zend_bool persistent MYSQLND_MEM_D) +{ + return pecalloc(nmemb, size, persistent); +} +/* }}} */ + + +/* {{{ mysqlnd_zend_mm_erealloc */ +static void * mysqlnd_zend_mm_erealloc(void *ptr, size_t new_size MYSQLND_MEM_D) +{ + return erealloc(ptr, new_size); +} +/* }}} */ + + +/* {{{ mysqlnd_zend_mm_perealloc */ +static void * mysqlnd_zend_mm_perealloc(void *ptr, size_t new_size, zend_bool persistent MYSQLND_MEM_D) +{ + return perealloc(ptr, new_size, persistent); +} +/* }}} */ + + +/* {{{ mysqlnd_zend_mm_efree */ +static void mysqlnd_zend_mm_efree(void * ptr MYSQLND_MEM_D) +{ + efree(ptr); +} +/* }}} */ + + +/* {{{ mysqlnd_zend_mm_pefree */ +static void mysqlnd_zend_mm_pefree(void * ptr, zend_bool persistent MYSQLND_MEM_D) +{ + pefree(ptr, persistent); +} +/* }}} */ + + +/* {{{ mysqlnd_zend_mm_malloc */ +static void * mysqlnd_zend_mm_malloc(size_t size MYSQLND_MEM_D) +{ + return malloc(size); +} +/* }}} */ + + +/* {{{ mysqlnd_zend_mm_calloc */ +static void * mysqlnd_zend_mm_calloc(unsigned int nmemb, size_t size MYSQLND_MEM_D) +{ + return calloc(nmemb, size); +} +/* }}} */ + + +/* {{{ mysqlnd_zend_mm_realloc */ +static void * mysqlnd_zend_mm_realloc(void * ptr, size_t new_size MYSQLND_MEM_D) +{ + return realloc(ptr, new_size); +} +/* }}} */ + + +/* {{{ mysqlnd_zend_mm_free */ +static void mysqlnd_zend_mm_free(void * ptr MYSQLND_MEM_D) +{ + free(ptr); +} +/* }}} */ + + +/* {{{ mysqlnd_zend_mm_pestrndup */ +static char * mysqlnd_zend_mm_pestrndup(const char * const ptr, size_t length, zend_bool persistent MYSQLND_MEM_D) +{ + return pestrndup(ptr, length, persistent); +} +/* }}} */ + + +/* {{{ mysqlnd_zend_mm_pestrdup */ +static char * mysqlnd_zend_mm_pestrdup(const char * const ptr, zend_bool persistent MYSQLND_MEM_D) +{ + return pestrdup(ptr, persistent); +} +/* }}} */ + +#endif + + +PHPAPI struct st_mysqlnd_allocator_methods mysqlnd_allocator = +{ +#if MYSQLND_DEBUG_MEMORY + _mysqlnd_emalloc, + _mysqlnd_pemalloc, + _mysqlnd_ecalloc, + _mysqlnd_pecalloc, + _mysqlnd_erealloc, + _mysqlnd_perealloc, + _mysqlnd_efree, + _mysqlnd_pefree, + _mysqlnd_malloc, + _mysqlnd_calloc, + _mysqlnd_realloc, + _mysqlnd_free, + _mysqlnd_pestrndup, + _mysqlnd_pestrdup +#else + mysqlnd_zend_mm_emalloc, + mysqlnd_zend_mm_pemalloc, + mysqlnd_zend_mm_ecalloc, + mysqlnd_zend_mm_pecalloc, + mysqlnd_zend_mm_erealloc, + mysqlnd_zend_mm_perealloc, + mysqlnd_zend_mm_efree, + mysqlnd_zend_mm_pefree, + mysqlnd_zend_mm_malloc, + mysqlnd_zend_mm_calloc, + mysqlnd_zend_mm_realloc, + mysqlnd_zend_mm_free, + mysqlnd_zend_mm_pestrndup, + mysqlnd_zend_mm_pestrdup +#endif +}; + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/mysqlnd/mysqlnd_alloc.h b/ext/mysqlnd/mysqlnd_alloc.h new file mode 100644 index 0000000000..b5fb862a79 --- /dev/null +++ b/ext/mysqlnd/mysqlnd_alloc.h @@ -0,0 +1,92 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 2006-2011 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Georg Richter | + | Andrey Hristov | + | Ulf Wendel | + +----------------------------------------------------------------------+ +*/ + +/* $Id: mysqlnd_debug.h 306938 2011-01-01 02:17:06Z felipe $ */ +/* $Id: mysqlnd_debug.h 306938 2011-01-01 02:17:06Z felipe $ */ + +#ifndef MYSQLND_ALLOC_H +#define MYSQLND_ALLOC_H + +extern const char * mysqlnd_debug_std_no_trace_funcs[]; + +#define MYSQLND_MEM_D TSRMLS_DC ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC +#define MYSQLND_MEM_C TSRMLS_CC ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC + +struct st_mysqlnd_allocator_methods +{ + void * (*m_emalloc)(size_t size MYSQLND_MEM_D); + void * (*m_pemalloc)(size_t size, zend_bool persistent MYSQLND_MEM_D); + void * (*m_ecalloc)(unsigned int nmemb, size_t size MYSQLND_MEM_D); + void * (*m_pecalloc)(unsigned int nmemb, size_t size, zend_bool persistent MYSQLND_MEM_D); + void * (*m_erealloc)(void *ptr, size_t new_size MYSQLND_MEM_D); + void * (*m_perealloc)(void *ptr, size_t new_size, zend_bool persistent MYSQLND_MEM_D); + void (*m_efree)(void *ptr MYSQLND_MEM_D); + void (*m_pefree)(void *ptr, zend_bool persistent MYSQLND_MEM_D); + void * (*m_malloc)(size_t size MYSQLND_MEM_D); + void * (*m_calloc)(unsigned int nmemb, size_t size MYSQLND_MEM_D); + void * (*m_realloc)(void *ptr, size_t new_size MYSQLND_MEM_D); + void (*m_free)(void *ptr MYSQLND_MEM_D); + char * (*m_pestrndup)(const char * const ptr, size_t size, zend_bool persistent MYSQLND_MEM_D); + char * (*m_pestrdup)(const char * const ptr, zend_bool persistent MYSQLND_MEM_D); +}; + +PHPAPI extern struct st_mysqlnd_allocator_methods mysqlnd_allocator; + +PHPAPI void * _mysqlnd_emalloc(size_t size MYSQLND_MEM_D); +PHPAPI void * _mysqlnd_pemalloc(size_t size, zend_bool persistent MYSQLND_MEM_D); +PHPAPI void * _mysqlnd_ecalloc(unsigned int nmemb, size_t size MYSQLND_MEM_D); +PHPAPI void * _mysqlnd_pecalloc(unsigned int nmemb, size_t size, zend_bool persistent MYSQLND_MEM_D); +PHPAPI void * _mysqlnd_erealloc(void *ptr, size_t new_size MYSQLND_MEM_D); +PHPAPI void * _mysqlnd_perealloc(void *ptr, size_t new_size, zend_bool persistent MYSQLND_MEM_D); +PHPAPI void _mysqlnd_efree(void *ptr MYSQLND_MEM_D); +PHPAPI void _mysqlnd_pefree(void *ptr, zend_bool persistent MYSQLND_MEM_D); +PHPAPI void * _mysqlnd_malloc(size_t size MYSQLND_MEM_D); +PHPAPI void * _mysqlnd_calloc(unsigned int nmemb, size_t size MYSQLND_MEM_D); +PHPAPI void * _mysqlnd_realloc(void *ptr, size_t new_size MYSQLND_MEM_D); +PHPAPI void _mysqlnd_free(void *ptr MYSQLND_MEM_D); +PHPAPI char * _mysqlnd_pestrndup(const char * const ptr, size_t size, zend_bool persistent MYSQLND_MEM_D); +PHPAPI char * _mysqlnd_pestrdup(const char * const ptr, zend_bool persistent MYSQLND_MEM_D); + + +#define mnd_emalloc(size) mysqlnd_allocator.m_emalloc((size) MYSQLND_MEM_C) +#define mnd_pemalloc(size, pers) mysqlnd_allocator.m_pemalloc((size), (pers) MYSQLND_MEM_C) +#define mnd_ecalloc(nmemb, size) mysqlnd_allocator.m_ecalloc((nmemb), (size) MYSQLND_MEM_C) +#define mnd_pecalloc(nmemb, size, p) mysqlnd_allocator.m_pecalloc((nmemb), (size), (p) MYSQLND_MEM_C) +#define mnd_erealloc(ptr, new_size) mysqlnd_allocator.m_erealloc((ptr), (new_size) MYSQLND_MEM_C) +#define mnd_perealloc(ptr, new_size, p) mysqlnd_allocator.m_perealloc((ptr), (new_size), (p) MYSQLND_MEM_C) +#define mnd_efree(ptr) mysqlnd_allocator.m_efree((ptr) MYSQLND_MEM_C) +#define mnd_pefree(ptr, pers) mysqlnd_allocator.m_pefree((ptr), (pers) MYSQLND_MEM_C) +#define mnd_malloc(size) mysqlnd_allocator.m_malloc((size) MYSQLND_MEM_C) +#define mnd_calloc(nmemb, size) mysqlnd_allocator.m_calloc((nmemb), (size) MYSQLND_MEM_C) +#define mnd_realloc(ptr, new_size) mysqlnd_allocator.m_realloc((ptr), (new_size) MYSQLND_MEM_C) +#define mnd_free(ptr) mysqlnd_allocator.m_free((ptr) MYSQLND_MEM_C) +#define mnd_pestrndup(ptr, size, pers) mysqlnd_allocator.m_pestrndup((ptr), (size), (pers) MYSQLND_MEM_C) +#define mnd_pestrdup(ptr, pers) mysqlnd_allocator.m_pestrdup((ptr), (pers) MYSQLND_MEM_C) + +#endif /* MYSQLND_ALLOC_H */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/mysqlnd/mysqlnd_bt.c b/ext/mysqlnd/mysqlnd_bt.c new file mode 100644 index 0000000000..4863012409 --- /dev/null +++ b/ext/mysqlnd/mysqlnd_bt.c @@ -0,0 +1,483 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 2006-2011 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Georg Richter | + | Andrey Hristov | + | Ulf Wendel | + +----------------------------------------------------------------------+ +*/ + +/* $Id: mysqlnd_debug.c 309303 2011-03-16 12:42:59Z andrey $ */ + +#include "php.h" + +/* Follows code borrowed from zend_builtin_functions.c because the functions there are static */ + +#if MYSQLND_UNICODE +/* {{{ gettraceasstring() macros */ +#define TRACE_APPEND_CHR(chr) \ + *str = (char*)erealloc(*str, *len + 1 + 1); \ + (*str)[(*len)++] = chr + +#define TRACE_APPEND_STRL(val, vallen) \ + { \ + int l = vallen; \ + *str = (char*)erealloc(*str, *len + l + 1); \ + memcpy((*str) + *len, val, l); \ + *len += l; \ + } + +#define TRACE_APPEND_USTRL(val, vallen) \ + { \ + zval tmp, copy; \ + int use_copy; \ + ZVAL_UNICODEL(&tmp, val, vallen, 1); \ + zend_make_printable_zval(&tmp, ©, &use_copy); \ + TRACE_APPEND_STRL(Z_STRVAL(copy), Z_STRLEN(copy)); \ + zval_dtor(©); \ + zval_dtor(&tmp); \ + } + +#define TRACE_APPEND_ZVAL(zv) \ + if (Z_TYPE_P((zv)) == IS_UNICODE) { \ + zval copy; \ + int use_copy; \ + zend_make_printable_zval((zv), ©, &use_copy); \ + TRACE_APPEND_STRL(Z_STRVAL(copy), Z_STRLEN(copy)); \ + zval_dtor(©); \ + } else { \ + TRACE_APPEND_STRL(Z_STRVAL_P((zv)), Z_STRLEN_P((zv))); \ + } + +#define TRACE_APPEND_STR(val) \ + TRACE_APPEND_STRL(val, sizeof(val)-1) + +#define TRACE_APPEND_KEY(key) \ + if (zend_ascii_hash_find(ht, key, sizeof(key), (void**)&tmp) == SUCCESS) { \ + if (Z_TYPE_PP(tmp) == IS_UNICODE) { \ + zval copy; \ + int use_copy; \ + zend_make_printable_zval(*tmp, ©, &use_copy); \ + TRACE_APPEND_STRL(Z_STRVAL(copy), Z_STRLEN(copy)); \ + zval_dtor(©); \ + } else { \ + TRACE_APPEND_STRL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); \ + } \ + } +/* }}} */ + + +/* {{{ mysqlnd_build_trace_args */ +static int mysqlnd_build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) +{ + char **str; + int *len; + + str = va_arg(args, char**); + len = va_arg(args, int*); + + /* the trivial way would be to do: + * conver_to_string_ex(arg); + * append it and kill the now tmp arg. + * but that could cause some E_NOTICE and also damn long lines. + */ + + switch (Z_TYPE_PP(arg)) { + case IS_NULL: + TRACE_APPEND_STR("NULL, "); + break; + case IS_STRING: { + int l_added; + TRACE_APPEND_CHR('\''); + if (Z_STRLEN_PP(arg) > 15) { + TRACE_APPEND_STRL(Z_STRVAL_PP(arg), 15); + TRACE_APPEND_STR("...', "); + l_added = 15 + 6 + 1; /* +1 because of while (--l_added) */ + } else { + l_added = Z_STRLEN_PP(arg); + TRACE_APPEND_STRL(Z_STRVAL_PP(arg), l_added); + TRACE_APPEND_STR("', "); + l_added += 3 + 1; + } + while (--l_added) { + if ((unsigned char)(*str)[*len - l_added] < 32) { + (*str)[*len - l_added] = '?'; + } + } + break; + } + case IS_UNICODE: { + int l_added; + + /* + * We do not want to apply current error mode here, since + * zend_make_printable_zval() uses output encoding converter. + * Temporarily set output encoding converter to escape offending + * chars with \uXXXX notation. + */ + zend_set_converter_error_mode(ZEND_U_CONVERTER(UG(output_encoding_conv)), ZEND_FROM_UNICODE, ZEND_CONV_ERROR_ESCAPE_JAVA); + TRACE_APPEND_CHR('\''); + if (Z_USTRLEN_PP(arg) > 15) { + TRACE_APPEND_USTRL(Z_USTRVAL_PP(arg), 15); + TRACE_APPEND_STR("...', "); + l_added = 15 + 6 + 1; /* +1 because of while (--l_added) */ + } else { + l_added = Z_USTRLEN_PP(arg); + TRACE_APPEND_USTRL(Z_USTRVAL_PP(arg), l_added); + TRACE_APPEND_STR("', "); + l_added += 3 + 1; + } + /* + * Reset output encoding converter error mode. + */ + zend_set_converter_error_mode(ZEND_U_CONVERTER(UG(output_encoding_conv)), ZEND_FROM_UNICODE, UG(from_error_mode)); + while (--l_added) { + if ((unsigned char)(*str)[*len - l_added] < 32) { + (*str)[*len - l_added] = '?'; + } + } + break; + } + case IS_BOOL: + if (Z_LVAL_PP(arg)) { + TRACE_APPEND_STR("true, "); + } else { + TRACE_APPEND_STR("false, "); + } + break; + case IS_RESOURCE: + TRACE_APPEND_STR("Resource id #"); + /* break; */ + case IS_LONG: { + long lval = Z_LVAL_PP(arg); + char s_tmp[MAX_LENGTH_OF_LONG + 1]; + int l_tmp = zend_sprintf(s_tmp, "%ld", lval); /* SAFE */ + TRACE_APPEND_STRL(s_tmp, l_tmp); + TRACE_APPEND_STR(", "); + break; + } + case IS_DOUBLE: { + double dval = Z_DVAL_PP(arg); + char *s_tmp; + int l_tmp; + + s_tmp = emalloc(MAX_LENGTH_OF_DOUBLE + EG(precision) + 1); + l_tmp = zend_sprintf(s_tmp, "%.*G", (int) EG(precision), dval); /* SAFE */ + TRACE_APPEND_STRL(s_tmp, l_tmp); + /* %G already handles removing trailing zeros from the fractional part, yay */ + efree(s_tmp); + TRACE_APPEND_STR(", "); + break; + } + case IS_ARRAY: + TRACE_APPEND_STR("Array, "); + break; + case IS_OBJECT: { + zval tmp; + zstr class_name; + zend_uint class_name_len; + int dup; + + TRACE_APPEND_STR("Object("); + + dup = zend_get_object_classname(*arg, &class_name, &class_name_len TSRMLS_CC); + + ZVAL_UNICODEL(&tmp, class_name.u, class_name_len, 1); + convert_to_string_with_converter(&tmp, ZEND_U_CONVERTER(UG(output_encoding_conv))); + TRACE_APPEND_STRL(Z_STRVAL(tmp), Z_STRLEN(tmp)); + zval_dtor(&tmp); + + if(!dup) { + efree(class_name.v); + } + + TRACE_APPEND_STR("), "); + break; + } + default: + break; + } + return ZEND_HASH_APPLY_KEEP; +} +/* }}} */ + + +static int mysqlnd_build_trace_string(zval **frame TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ +{ + char *s_tmp, **str; + int *len, *num; + long line; + HashTable *ht = Z_ARRVAL_PP(frame); + zval **file, **tmp; + uint * level; + + level = va_arg(args, uint *); + str = va_arg(args, char**); + len = va_arg(args, int*); + num = va_arg(args, int*); + + if (!*level) { + return ZEND_HASH_APPLY_KEEP; + } + --*level; + + s_tmp = emalloc(1 + MAX_LENGTH_OF_LONG + 1 + 1); + sprintf(s_tmp, "#%d ", (*num)++); + TRACE_APPEND_STRL(s_tmp, strlen(s_tmp)); + efree(s_tmp); + if (zend_ascii_hash_find(ht, "file", sizeof("file"), (void**)&file) == SUCCESS) { + if (zend_ascii_hash_find(ht, "line", sizeof("line"), (void**)&tmp) == SUCCESS) { + line = Z_LVAL_PP(tmp); + } else { + line = 0; + } + TRACE_APPEND_ZVAL(*file); + s_tmp = emalloc(MAX_LENGTH_OF_LONG + 2 + 1); + sprintf(s_tmp, "(%ld): ", line); + TRACE_APPEND_STRL(s_tmp, strlen(s_tmp)); + efree(s_tmp); + } else { + TRACE_APPEND_STR("[internal function]: "); + } + TRACE_APPEND_KEY("class"); + TRACE_APPEND_KEY("type"); + TRACE_APPEND_KEY("function"); + TRACE_APPEND_CHR('('); + if (zend_ascii_hash_find(ht, "args", sizeof("args"), (void**)&tmp) == SUCCESS) { + int last_len = *len; + zend_hash_apply_with_arguments(Z_ARRVAL_PP(tmp) TSRMLS_CC, (apply_func_args_t)mysqlnd_build_trace_args, 2, str, len); + if (last_len != *len) { + *len -= 2; /* remove last ', ' */ + } + } + TRACE_APPEND_STR(")\n"); + return ZEND_HASH_APPLY_KEEP; +} +/* }}} */ + + +#else /* PHP 5*/ + + +/* {{{ gettraceasstring() macros */ +#define TRACE_APPEND_CHR(chr) \ + *str = (char*)erealloc(*str, *len + 1 + 1); \ + (*str)[(*len)++] = chr + +#define TRACE_APPEND_STRL(val, vallen) \ + { \ + int l = vallen; \ + *str = (char*)erealloc(*str, *len + l + 1); \ + memcpy((*str) + *len, val, l); \ + *len += l; \ + } + +#define TRACE_APPEND_STR(val) \ + TRACE_APPEND_STRL(val, sizeof(val)-1) + +#define TRACE_APPEND_KEY(key) \ + if (zend_hash_find(ht, key, sizeof(key), (void**)&tmp) == SUCCESS) { \ + TRACE_APPEND_STRL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); \ + } + +/* }}} */ + + +static int mysqlnd_build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ +{ + char **str; + int *len; + + str = va_arg(args, char**); + len = va_arg(args, int*); + + /* the trivial way would be to do: + * conver_to_string_ex(arg); + * append it and kill the now tmp arg. + * but that could cause some E_NOTICE and also damn long lines. + */ + + switch (Z_TYPE_PP(arg)) { + case IS_NULL: + TRACE_APPEND_STR("NULL, "); + break; + case IS_STRING: { + int l_added; + TRACE_APPEND_CHR('\''); + if (Z_STRLEN_PP(arg) > 15) { + TRACE_APPEND_STRL(Z_STRVAL_PP(arg), 15); + TRACE_APPEND_STR("...', "); + l_added = 15 + 6 + 1; /* +1 because of while (--l_added) */ + } else { + l_added = Z_STRLEN_PP(arg); + TRACE_APPEND_STRL(Z_STRVAL_PP(arg), l_added); + TRACE_APPEND_STR("', "); + l_added += 3 + 1; + } + while (--l_added) { + if ((*str)[*len - l_added] < 32) { + (*str)[*len - l_added] = '?'; + } + } + break; + } + case IS_BOOL: + if (Z_LVAL_PP(arg)) { + TRACE_APPEND_STR("true, "); + } else { + TRACE_APPEND_STR("false, "); + } + break; + case IS_RESOURCE: + TRACE_APPEND_STR("Resource id #"); + /* break; */ + case IS_LONG: { + long lval = Z_LVAL_PP(arg); + char s_tmp[MAX_LENGTH_OF_LONG + 1]; + int l_tmp = zend_sprintf(s_tmp, "%ld", lval); /* SAFE */ + TRACE_APPEND_STRL(s_tmp, l_tmp); + TRACE_APPEND_STR(", "); + break; + } + case IS_DOUBLE: { + double dval = Z_DVAL_PP(arg); + char *s_tmp; + int l_tmp; + + s_tmp = emalloc(MAX_LENGTH_OF_DOUBLE + EG(precision) + 1); + l_tmp = zend_sprintf(s_tmp, "%.*G", (int) EG(precision), dval); /* SAFE */ + TRACE_APPEND_STRL(s_tmp, l_tmp); + /* %G already handles removing trailing zeros from the fractional part, yay */ + efree(s_tmp); + TRACE_APPEND_STR(", "); + break; + } + case IS_ARRAY: + TRACE_APPEND_STR("Array, "); + break; + case IS_OBJECT: { + char *class_name; + zend_uint class_name_len; + int dupl; + + TRACE_APPEND_STR("Object("); + + dupl = zend_get_object_classname(*arg, &class_name, &class_name_len TSRMLS_CC); + + TRACE_APPEND_STRL(class_name, class_name_len); + if (!dupl) { + efree(class_name); + } + + TRACE_APPEND_STR("), "); + break; + } + default: + break; + } + return ZEND_HASH_APPLY_KEEP; +} +/* }}} */ + +static int mysqlnd_build_trace_string(zval **frame TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ +{ + char *s_tmp, **str; + int *len, *num; + long line; + HashTable *ht = Z_ARRVAL_PP(frame); + zval **file, **tmp; + uint * level; + + level = va_arg(args, uint *); + str = va_arg(args, char**); + len = va_arg(args, int*); + num = va_arg(args, int*); + + if (!*level) { + return ZEND_HASH_APPLY_KEEP; + } + --*level; + + s_tmp = emalloc(1 + MAX_LENGTH_OF_LONG + 1 + 1); + sprintf(s_tmp, "#%d ", (*num)++); + TRACE_APPEND_STRL(s_tmp, strlen(s_tmp)); + efree(s_tmp); + if (zend_hash_find(ht, "file", sizeof("file"), (void**)&file) == SUCCESS) { + if (zend_hash_find(ht, "line", sizeof("line"), (void**)&tmp) == SUCCESS) { + line = Z_LVAL_PP(tmp); + } else { + line = 0; + } + s_tmp = emalloc(Z_STRLEN_PP(file) + MAX_LENGTH_OF_LONG + 4 + 1); + sprintf(s_tmp, "%s(%ld): ", Z_STRVAL_PP(file), line); + TRACE_APPEND_STRL(s_tmp, strlen(s_tmp)); + efree(s_tmp); + } else { + TRACE_APPEND_STR("[internal function]: "); + } + TRACE_APPEND_KEY("class"); + TRACE_APPEND_KEY("type"); + TRACE_APPEND_KEY("function"); + TRACE_APPEND_CHR('('); + if (zend_hash_find(ht, "args", sizeof("args"), (void**)&tmp) == SUCCESS) { + int last_len = *len; + zend_hash_apply_with_arguments(Z_ARRVAL_PP(tmp) TSRMLS_CC, (apply_func_args_t)mysqlnd_build_trace_args, 2, str, len); + if (last_len != *len) { + *len -= 2; /* remove last ', ' */ + } + } + TRACE_APPEND_STR(")\n"); + return ZEND_HASH_APPLY_KEEP; +} +/* }}} */ +#endif + + +PHPAPI char * mysqlnd_get_backtrace(uint max_levels, size_t * length TSRMLS_DC) +{ + zval *trace; + char *res = estrdup(""), **str = &res, *s_tmp; + int res_len = 0, *len = &res_len, num = 0; + if (max_levels == 0) { + max_levels = 99999; + } + + MAKE_STD_ZVAL(trace); + zend_fetch_debug_backtrace(trace, 0, 0 TSRMLS_CC); + + zend_hash_apply_with_arguments(Z_ARRVAL_P(trace) TSRMLS_CC, (apply_func_args_t)mysqlnd_build_trace_string, 4, &max_levels, str, len, &num); + zval_ptr_dtor(&trace); + + if (max_levels) { + s_tmp = emalloc(1 + MAX_LENGTH_OF_LONG + 7 + 1); + sprintf(s_tmp, "#%d {main}", num); + TRACE_APPEND_STRL(s_tmp, strlen(s_tmp)); + efree(s_tmp); + } + + res[res_len] = '\0'; + *length = res_len; + + return res; +} + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/mysqlnd/mysqlnd_debug.c b/ext/mysqlnd/mysqlnd_debug.c index 21cd71c620..7d2da7e03e 100644 --- a/ext/mysqlnd/mysqlnd_debug.c +++ b/ext/mysqlnd/mysqlnd_debug.c @@ -24,9 +24,6 @@ #include "mysqlnd.h" #include "mysqlnd_priv.h" #include "mysqlnd_debug.h" -#include "mysqlnd_wireprotocol.h" -#include "mysqlnd_statistics.h" -#include "zend_builtin_functions.h" static const char * const mysqlnd_debug_default_trace_file = "/tmp/mysqlnd.trace"; @@ -36,41 +33,6 @@ static const char * const mysqlnd_debug_default_trace_file = "/tmp/mysqlnd.trace #define MYSQLND_ZTS(self) #endif -static const char mysqlnd_emalloc_name[] = "_mysqlnd_emalloc"; -static const char mysqlnd_pemalloc_name[] = "_mysqlnd_pemalloc"; -static const char mysqlnd_ecalloc_name[] = "_mysqlnd_ecalloc"; -static const char mysqlnd_pecalloc_name[] = "_mysqlnd_pecalloc"; -static const char mysqlnd_erealloc_name[] = "_mysqlnd_erealloc"; -static const char mysqlnd_perealloc_name[] = "_mysqlnd_perealloc"; -static const char mysqlnd_efree_name[] = "_mysqlnd_efree"; -static const char mysqlnd_pefree_name[] = "_mysqlnd_pefree"; -static const char mysqlnd_malloc_name[] = "_mysqlnd_malloc"; -static const char mysqlnd_calloc_name[] = "_mysqlnd_calloc"; -static const char mysqlnd_realloc_name[] = "_mysqlnd_realloc"; -static const char mysqlnd_free_name[] = "_mysqlnd_free"; -static const char mysqlnd_pestrndup_name[] = "_mysqlnd_pestrndup"; -static const char mysqlnd_pestrdup_name[] = "_mysqlnd_pestrdup"; - -const char * mysqlnd_debug_std_no_trace_funcs[] = -{ - mysqlnd_emalloc_name, - mysqlnd_ecalloc_name, - mysqlnd_efree_name, - mysqlnd_erealloc_name, - mysqlnd_pemalloc_name, - mysqlnd_pecalloc_name, - mysqlnd_pefree_name, - mysqlnd_perealloc_name, - mysqlnd_malloc_name, - mysqlnd_calloc_name, - mysqlnd_realloc_name, - mysqlnd_free_name, - mysqlnd_pestrndup_name, - mysqlnd_read_header_name, - mysqlnd_read_body_name, - NULL /* must be always last */ -}; - /* {{{ mysqlnd_debug::open */ static enum_func_status @@ -805,1058 +767,6 @@ PHPAPI void _mysqlnd_debug(const char * mode TSRMLS_DC) /* }}} */ -#if ZEND_DEBUG -#else -#define __zend_filename "/unknown/unknown" -#define __zend_lineno 0 -#endif - -#define REAL_SIZE(s) (collect_memory_statistics? (s) + sizeof(size_t) : (s)) -#define REAL_PTR(p) (collect_memory_statistics && (p)? (((char *)(p)) - sizeof(size_t)) : (p)) -#define FAKE_PTR(p) (collect_memory_statistics && (p)? (((char *)(p)) + sizeof(size_t)) : (p)) - -/* {{{ _mysqlnd_emalloc */ -void * _mysqlnd_emalloc(size_t size MYSQLND_MEM_D) -{ - void *ret; - zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); - long * threshold = &MYSQLND_G(debug_emalloc_fail_threshold); - DBG_ENTER(mysqlnd_emalloc_name); - - DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); - -#if PHP_DEBUG - /* -1 is also "true" */ - if (*threshold) { -#endif - ret = emalloc(REAL_SIZE(size)); -#if PHP_DEBUG - --*threshold; - } else if (*threshold == 0) { - ret = NULL; - } -#endif - - DBG_INF_FMT("size=%lu ptr=%p", size, ret); - - if (ret && collect_memory_statistics) { - *(size_t *) ret = size; - MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_EMALLOC_COUNT, 1, STAT_MEM_EMALLOC_AMOUNT, size); - } - DBG_RETURN(FAKE_PTR(ret)); -} -/* }}} */ - - -/* {{{ _mysqlnd_pemalloc */ -void * _mysqlnd_pemalloc(size_t size, zend_bool persistent MYSQLND_MEM_D) -{ - void *ret; - zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); - long * threshold = persistent? &MYSQLND_G(debug_malloc_fail_threshold):&MYSQLND_G(debug_emalloc_fail_threshold); - DBG_ENTER(mysqlnd_pemalloc_name); - DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); - -#if PHP_DEBUG - /* -1 is also "true" */ - if (*threshold) { -#endif - ret = pemalloc(REAL_SIZE(size), persistent); -#if PHP_DEBUG - --*threshold; - } else if (*threshold == 0) { - ret = NULL; - } -#endif - - DBG_INF_FMT("size=%lu ptr=%p persistent=%u", size, ret, persistent); - - if (ret && collect_memory_statistics) { - enum mysqlnd_collected_stats s1 = persistent? STAT_MEM_MALLOC_COUNT:STAT_MEM_EMALLOC_COUNT; - enum mysqlnd_collected_stats s2 = persistent? STAT_MEM_MALLOC_AMOUNT:STAT_MEM_EMALLOC_AMOUNT; - *(size_t *) ret = size; - MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(s1, 1, s2, size); - } - - DBG_RETURN(FAKE_PTR(ret)); -} -/* }}} */ - - -/* {{{ _mysqlnd_ecalloc */ -void * _mysqlnd_ecalloc(unsigned int nmemb, size_t size MYSQLND_MEM_D) -{ - void *ret; - zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); - long * threshold = &MYSQLND_G(debug_ecalloc_fail_threshold); - DBG_ENTER(mysqlnd_ecalloc_name); - DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); - DBG_INF_FMT("before: %lu", zend_memory_usage(FALSE TSRMLS_CC)); - -#if PHP_DEBUG - /* -1 is also "true" */ - if (*threshold) { -#endif - ret = ecalloc(nmemb, REAL_SIZE(size)); -#if PHP_DEBUG - --*threshold; - } else if (*threshold == 0) { - ret = NULL; - } -#endif - - DBG_INF_FMT("after : %lu", zend_memory_usage(FALSE TSRMLS_CC)); - DBG_INF_FMT("size=%lu ptr=%p", size, ret); - if (ret && collect_memory_statistics) { - *(size_t *) ret = size; - MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_ECALLOC_COUNT, 1, STAT_MEM_ECALLOC_AMOUNT, size); - } - DBG_RETURN(FAKE_PTR(ret)); -} -/* }}} */ - - -/* {{{ _mysqlnd_pecalloc */ -void * _mysqlnd_pecalloc(unsigned int nmemb, size_t size, zend_bool persistent MYSQLND_MEM_D) -{ - void *ret; - zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); - long * threshold = persistent? &MYSQLND_G(debug_calloc_fail_threshold):&MYSQLND_G(debug_ecalloc_fail_threshold); - DBG_ENTER(mysqlnd_pecalloc_name); - DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); - -#if PHP_DEBUG - /* -1 is also "true" */ - if (*threshold) { -#endif - ret = pecalloc(nmemb, REAL_SIZE(size), persistent); -#if PHP_DEBUG - --*threshold; - } else if (*threshold == 0) { - ret = NULL; - } -#endif - - DBG_INF_FMT("size=%lu ptr=%p", size, ret); - - if (ret && collect_memory_statistics) { - enum mysqlnd_collected_stats s1 = persistent? STAT_MEM_CALLOC_COUNT:STAT_MEM_ECALLOC_COUNT; - enum mysqlnd_collected_stats s2 = persistent? STAT_MEM_CALLOC_AMOUNT:STAT_MEM_ECALLOC_AMOUNT; - *(size_t *) ret = size; - MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(s1, 1, s2, size); - } - - DBG_RETURN(FAKE_PTR(ret)); -} -/* }}} */ - - -/* {{{ _mysqlnd_erealloc */ -void * _mysqlnd_erealloc(void *ptr, size_t new_size MYSQLND_MEM_D) -{ - void *ret; - zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); - size_t old_size = collect_memory_statistics && ptr? *(size_t *) (((char*)ptr) - sizeof(size_t)) : 0; - long * threshold = &MYSQLND_G(debug_erealloc_fail_threshold); - DBG_ENTER(mysqlnd_erealloc_name); - DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); - DBG_INF_FMT("ptr=%p old_size=%lu, new_size=%lu", ptr, old_size, new_size); - -#if PHP_DEBUG - /* -1 is also "true" */ - if (*threshold) { -#endif - ret = erealloc(REAL_PTR(ptr), REAL_SIZE(new_size)); -#if PHP_DEBUG - --*threshold; - } else if (*threshold == 0) { - ret = NULL; - } -#endif - - DBG_INF_FMT("new_ptr=%p", (char*)ret); - if (ret && collect_memory_statistics) { - *(size_t *) ret = new_size; - MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_EREALLOC_COUNT, 1, STAT_MEM_EREALLOC_AMOUNT, new_size); - } - DBG_RETURN(FAKE_PTR(ret)); -} -/* }}} */ - - -/* {{{ _mysqlnd_perealloc */ -void * _mysqlnd_perealloc(void *ptr, size_t new_size, zend_bool persistent MYSQLND_MEM_D) -{ - void *ret; - zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); - size_t old_size = collect_memory_statistics && ptr? *(size_t *) (((char*)ptr) - sizeof(size_t)) : 0; - long * threshold = persistent? &MYSQLND_G(debug_realloc_fail_threshold):&MYSQLND_G(debug_erealloc_fail_threshold); - DBG_ENTER(mysqlnd_perealloc_name); - DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); - DBG_INF_FMT("ptr=%p old_size=%lu new_size=%lu persistent=%u", ptr, old_size, new_size, persistent); - -#if PHP_DEBUG - /* -1 is also "true" */ - if (*threshold) { -#endif - ret = perealloc(REAL_PTR(ptr), REAL_SIZE(new_size), persistent); -#if PHP_DEBUG - --*threshold; - } else if (*threshold == 0) { - ret = NULL; - } -#endif - - DBG_INF_FMT("new_ptr=%p", (char*)ret); - - if (ret && collect_memory_statistics) { - enum mysqlnd_collected_stats s1 = persistent? STAT_MEM_REALLOC_COUNT:STAT_MEM_EREALLOC_COUNT; - enum mysqlnd_collected_stats s2 = persistent? STAT_MEM_REALLOC_AMOUNT:STAT_MEM_EREALLOC_AMOUNT; - *(size_t *) ret = new_size; - MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(s1, 1, s2, new_size); - } - DBG_RETURN(FAKE_PTR(ret)); -} -/* }}} */ - - -/* {{{ _mysqlnd_efree */ -void _mysqlnd_efree(void *ptr MYSQLND_MEM_D) -{ - size_t free_amount = 0; - zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); - DBG_ENTER(mysqlnd_efree_name); - DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); - DBG_INF_FMT("ptr=%p", ptr); - - if (ptr) { - if (collect_memory_statistics) { - free_amount = *(size_t *)(((char*)ptr) - sizeof(size_t)); - DBG_INF_FMT("ptr=%p size=%u", ((char*)ptr) - sizeof(size_t), (unsigned int) free_amount); - } - efree(REAL_PTR(ptr)); - } - - if (collect_memory_statistics) { - MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_EFREE_COUNT, 1, STAT_MEM_EFREE_AMOUNT, free_amount); - } - DBG_VOID_RETURN; -} -/* }}} */ - - -/* {{{ _mysqlnd_pefree */ -void _mysqlnd_pefree(void *ptr, zend_bool persistent MYSQLND_MEM_D) -{ - size_t free_amount = 0; - zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); - DBG_ENTER(mysqlnd_pefree_name); - DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); - DBG_INF_FMT("ptr=%p persistent=%u", ptr, persistent); - - if (ptr) { - if (collect_memory_statistics) { - free_amount = *(size_t *)(((char*)ptr) - sizeof(size_t)); - DBG_INF_FMT("ptr=%p size=%u", ((char*)ptr) - sizeof(size_t), (unsigned int) free_amount); - } - pefree(REAL_PTR(ptr), persistent); - } - - if (collect_memory_statistics) { - MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(persistent? STAT_MEM_FREE_COUNT:STAT_MEM_EFREE_COUNT, 1, - persistent? STAT_MEM_FREE_AMOUNT:STAT_MEM_EFREE_AMOUNT, free_amount); - } - DBG_VOID_RETURN; -} - - -/* {{{ _mysqlnd_malloc */ -void * _mysqlnd_malloc(size_t size MYSQLND_MEM_D) -{ - void *ret; - zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); - long * threshold = &MYSQLND_G(debug_malloc_fail_threshold); - DBG_ENTER(mysqlnd_malloc_name); - DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); - -#if PHP_DEBUG - /* -1 is also "true" */ - if (*threshold) { -#endif - ret = malloc(REAL_SIZE(size)); -#if PHP_DEBUG - --*threshold; - } else if (*threshold == 0) { - ret = NULL; - } -#endif - - DBG_INF_FMT("size=%lu ptr=%p", size, ret); - if (ret && collect_memory_statistics) { - *(size_t *) ret = size; - MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_MALLOC_COUNT, 1, STAT_MEM_MALLOC_AMOUNT, size); - } - DBG_RETURN(FAKE_PTR(ret)); -} -/* }}} */ - - -/* {{{ _mysqlnd_calloc */ -void * _mysqlnd_calloc(unsigned int nmemb, size_t size MYSQLND_MEM_D) -{ - void *ret; - zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); - long * threshold = &MYSQLND_G(debug_calloc_fail_threshold); - DBG_ENTER(mysqlnd_calloc_name); - DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); - -#if PHP_DEBUG - /* -1 is also "true" */ - if (*threshold) { -#endif - ret = calloc(nmemb, REAL_SIZE(size)); -#if PHP_DEBUG - --*threshold; - } else if (*threshold == 0) { - ret = NULL; - } -#endif - - DBG_INF_FMT("size=%lu ptr=%p", size, ret); - if (ret && collect_memory_statistics) { - *(size_t *) ret = size; - MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_CALLOC_COUNT, 1, STAT_MEM_CALLOC_AMOUNT, size); - } - DBG_RETURN(FAKE_PTR(ret)); -} -/* }}} */ - - -/* {{{ _mysqlnd_realloc */ -void * _mysqlnd_realloc(void *ptr, size_t new_size MYSQLND_MEM_D) -{ - void *ret; - zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); - long * threshold = &MYSQLND_G(debug_realloc_fail_threshold); - DBG_ENTER(mysqlnd_realloc_name); - DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); - DBG_INF_FMT("ptr=%p new_size=%lu ", new_size, ptr); - DBG_INF_FMT("before: %lu", zend_memory_usage(TRUE TSRMLS_CC)); - -#if PHP_DEBUG - /* -1 is also "true" */ - if (*threshold) { -#endif - ret = realloc(REAL_PTR(ptr), REAL_SIZE(new_size)); -#if PHP_DEBUG - --*threshold; - } else if (*threshold == 0) { - ret = NULL; - } -#endif - - DBG_INF_FMT("new_ptr=%p", (char*)ret); - - if (ret && collect_memory_statistics) { - *(size_t *) ret = new_size; - MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_REALLOC_COUNT, 1, STAT_MEM_REALLOC_AMOUNT, new_size); - } - DBG_RETURN(FAKE_PTR(ret)); -} -/* }}} */ - - -/* {{{ _mysqlnd_free */ -void _mysqlnd_free(void *ptr MYSQLND_MEM_D) -{ - size_t free_amount = 0; - zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); - DBG_ENTER(mysqlnd_free_name); - DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); - DBG_INF_FMT("ptr=%p", ptr); - - if (ptr) { - if (collect_memory_statistics) { - free_amount = *(size_t *)(((char*)ptr) - sizeof(size_t)); - DBG_INF_FMT("ptr=%p size=%u", ((char*)ptr) - sizeof(size_t), (unsigned int) free_amount); - } - free(REAL_PTR(ptr)); - } - - if (collect_memory_statistics) { - MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_FREE_COUNT, 1, STAT_MEM_FREE_AMOUNT, free_amount); - } - DBG_VOID_RETURN; -} -/* }}} */ - -#define SMART_STR_START_SIZE 2048 -#define SMART_STR_PREALLOC 512 -#include "ext/standard/php_smart_str.h" - - -/* {{{ _mysqlnd_pestrndup */ -char * _mysqlnd_pestrndup(const char * const ptr, size_t length, zend_bool persistent MYSQLND_MEM_D) -{ - char * ret; - zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); - DBG_ENTER(mysqlnd_pestrndup_name); - DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); - DBG_INF_FMT("ptr=%p", ptr); - - ret = pemalloc(REAL_SIZE(length) + 1, persistent); - { - size_t l = length; - char * p = (char *) ptr; - char * dest = (char *) FAKE_PTR(ret); - while (*p && l--) { - *dest++ = *p++; - } - *dest = '\0'; - } - - if (collect_memory_statistics) { - *(size_t *) ret = length; - MYSQLND_INC_GLOBAL_STATISTIC(persistent? STAT_MEM_STRNDUP_COUNT : STAT_MEM_ESTRNDUP_COUNT); - } - - DBG_RETURN(FAKE_PTR(ret)); -} -/* }}} */ - - -/* {{{ _mysqlnd_pestrdup */ -char * _mysqlnd_pestrdup(const char * const ptr, zend_bool persistent MYSQLND_MEM_D) -{ - char * ret; - smart_str tmp_str = {0, 0, 0}; - const char * p = ptr; - zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); - DBG_ENTER(mysqlnd_pestrdup_name); - DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); - DBG_INF_FMT("ptr=%p", ptr); - do { - smart_str_appendc(&tmp_str, *p); - } while (*p++); - - ret = pemalloc(tmp_str.len + sizeof(size_t), persistent); - memcpy(FAKE_PTR(ret), tmp_str.c, tmp_str.len); - - if (ret && collect_memory_statistics) { - *(size_t *) ret = tmp_str.len; - MYSQLND_INC_GLOBAL_STATISTIC(persistent? STAT_MEM_STRDUP_COUNT : STAT_MEM_ESTRDUP_COUNT); - } - smart_str_free(&tmp_str); - - DBG_RETURN(FAKE_PTR(ret)); -} -/* }}} */ - -#define MYSQLND_DEBUG_MEMORY 1 - -#if MYSQLND_DEBUG_MEMORY == 0 - -/* {{{ mysqlnd_zend_mm_emalloc */ -static void * mysqlnd_zend_mm_emalloc(size_t size MYSQLND_MEM_D) -{ - return emalloc(size); -} -/* }}} */ - - -/* {{{ mysqlnd_zend_mm_pemalloc */ -static void * mysqlnd_zend_mm_pemalloc(size_t size, zend_bool persistent MYSQLND_MEM_D) -{ - return pemalloc(size, persistent); -} -/* }}} */ - - -/* {{{ mysqlnd_zend_mm_ecalloc */ -static void * mysqlnd_zend_mm_ecalloc(unsigned int nmemb, size_t size MYSQLND_MEM_D) -{ - return ecalloc(nmemb, size); -} -/* }}} */ - - -/* {{{ mysqlnd_zend_mm_pecalloc */ -static void * mysqlnd_zend_mm_pecalloc(unsigned int nmemb, size_t size, zend_bool persistent MYSQLND_MEM_D) -{ - return pecalloc(nmemb, size, persistent); -} -/* }}} */ - - -/* {{{ mysqlnd_zend_mm_erealloc */ -static void * mysqlnd_zend_mm_erealloc(void *ptr, size_t new_size MYSQLND_MEM_D) -{ - return erealloc(ptr, new_size); -} -/* }}} */ - - -/* {{{ mysqlnd_zend_mm_perealloc */ -static void * mysqlnd_zend_mm_perealloc(void *ptr, size_t new_size, zend_bool persistent MYSQLND_MEM_D) -{ - return perealloc(ptr, new_size, persistent); -} -/* }}} */ - - -/* {{{ mysqlnd_zend_mm_efree */ -static void mysqlnd_zend_mm_efree(void * ptr MYSQLND_MEM_D) -{ - efree(ptr); -} -/* }}} */ - - -/* {{{ mysqlnd_zend_mm_pefree */ -static void mysqlnd_zend_mm_pefree(void * ptr, zend_bool persistent MYSQLND_MEM_D) -{ - pefree(ptr, persistent); -} -/* }}} */ - - -/* {{{ mysqlnd_zend_mm_malloc */ -static void * mysqlnd_zend_mm_malloc(size_t size MYSQLND_MEM_D) -{ - return malloc(size); -} -/* }}} */ - - -/* {{{ mysqlnd_zend_mm_calloc */ -static void * mysqlnd_zend_mm_calloc(unsigned int nmemb, size_t size MYSQLND_MEM_D) -{ - return calloc(nmemb, size); -} -/* }}} */ - - -/* {{{ mysqlnd_zend_mm_realloc */ -static void * mysqlnd_zend_mm_realloc(void * ptr, size_t new_size MYSQLND_MEM_D) -{ - return realloc(ptr, new_size); -} -/* }}} */ - - -/* {{{ mysqlnd_zend_mm_free */ -static void mysqlnd_zend_mm_free(void * ptr MYSQLND_MEM_D) -{ - free(ptr); -} -/* }}} */ - - -/* {{{ mysqlnd_zend_mm_pestrndup */ -static char * mysqlnd_zend_mm_pestrndup(const char * const ptr, size_t length, zend_bool persistent MYSQLND_MEM_D) -{ - return pestrndup(ptr, length, persistent); -} -/* }}} */ - - -/* {{{ mysqlnd_zend_mm_pestrdup */ -static char * mysqlnd_zend_mm_pestrdup(const char * const ptr, zend_bool persistent MYSQLND_MEM_D) -{ - return pestrdup(ptr, persistent); -} -/* }}} */ - -#endif - - -PHPAPI struct st_mysqlnd_allocator_methods mysqlnd_allocator = -{ -#if MYSQLND_DEBUG_MEMORY - _mysqlnd_emalloc, - _mysqlnd_pemalloc, - _mysqlnd_ecalloc, - _mysqlnd_pecalloc, - _mysqlnd_erealloc, - _mysqlnd_perealloc, - _mysqlnd_efree, - _mysqlnd_pefree, - _mysqlnd_malloc, - _mysqlnd_calloc, - _mysqlnd_realloc, - _mysqlnd_free, - _mysqlnd_pestrndup, - _mysqlnd_pestrdup -#else - mysqlnd_zend_mm_emalloc, - mysqlnd_zend_mm_pemalloc, - mysqlnd_zend_mm_ecalloc, - mysqlnd_zend_mm_pecalloc, - mysqlnd_zend_mm_erealloc, - mysqlnd_zend_mm_perealloc, - mysqlnd_zend_mm_efree, - mysqlnd_zend_mm_pefree, - mysqlnd_zend_mm_malloc, - mysqlnd_zend_mm_calloc, - mysqlnd_zend_mm_realloc, - mysqlnd_zend_mm_free, - mysqlnd_zend_mm_pestrndup, - mysqlnd_zend_mm_pestrdup -#endif -}; - - - -/* Follows code borrowed from zend_builtin_functions.c because the functions there are static */ - -#if MYSQLND_UNICODE -/* {{{ gettraceasstring() macros */ -#define TRACE_APPEND_CHR(chr) \ - *str = (char*)erealloc(*str, *len + 1 + 1); \ - (*str)[(*len)++] = chr - -#define TRACE_APPEND_STRL(val, vallen) \ - { \ - int l = vallen; \ - *str = (char*)erealloc(*str, *len + l + 1); \ - memcpy((*str) + *len, val, l); \ - *len += l; \ - } - -#define TRACE_APPEND_USTRL(val, vallen) \ - { \ - zval tmp, copy; \ - int use_copy; \ - ZVAL_UNICODEL(&tmp, val, vallen, 1); \ - zend_make_printable_zval(&tmp, ©, &use_copy); \ - TRACE_APPEND_STRL(Z_STRVAL(copy), Z_STRLEN(copy)); \ - zval_dtor(©); \ - zval_dtor(&tmp); \ - } - -#define TRACE_APPEND_ZVAL(zv) \ - if (Z_TYPE_P((zv)) == IS_UNICODE) { \ - zval copy; \ - int use_copy; \ - zend_make_printable_zval((zv), ©, &use_copy); \ - TRACE_APPEND_STRL(Z_STRVAL(copy), Z_STRLEN(copy)); \ - zval_dtor(©); \ - } else { \ - TRACE_APPEND_STRL(Z_STRVAL_P((zv)), Z_STRLEN_P((zv))); \ - } - -#define TRACE_APPEND_STR(val) \ - TRACE_APPEND_STRL(val, sizeof(val)-1) - -#define TRACE_APPEND_KEY(key) \ - if (zend_ascii_hash_find(ht, key, sizeof(key), (void**)&tmp) == SUCCESS) { \ - if (Z_TYPE_PP(tmp) == IS_UNICODE) { \ - zval copy; \ - int use_copy; \ - zend_make_printable_zval(*tmp, ©, &use_copy); \ - TRACE_APPEND_STRL(Z_STRVAL(copy), Z_STRLEN(copy)); \ - zval_dtor(©); \ - } else { \ - TRACE_APPEND_STRL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); \ - } \ - } -/* }}} */ - -/* {{{ mysqlnd_build_trace_args */ -static int mysqlnd_build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) -{ - char **str; - int *len; - - str = va_arg(args, char**); - len = va_arg(args, int*); - - /* the trivial way would be to do: - * conver_to_string_ex(arg); - * append it and kill the now tmp arg. - * but that could cause some E_NOTICE and also damn long lines. - */ - - switch (Z_TYPE_PP(arg)) { - case IS_NULL: - TRACE_APPEND_STR("NULL, "); - break; - case IS_STRING: { - int l_added; - TRACE_APPEND_CHR('\''); - if (Z_STRLEN_PP(arg) > 15) { - TRACE_APPEND_STRL(Z_STRVAL_PP(arg), 15); - TRACE_APPEND_STR("...', "); - l_added = 15 + 6 + 1; /* +1 because of while (--l_added) */ - } else { - l_added = Z_STRLEN_PP(arg); - TRACE_APPEND_STRL(Z_STRVAL_PP(arg), l_added); - TRACE_APPEND_STR("', "); - l_added += 3 + 1; - } - while (--l_added) { - if ((unsigned char)(*str)[*len - l_added] < 32) { - (*str)[*len - l_added] = '?'; - } - } - break; - } - case IS_UNICODE: { - int l_added; - - /* - * We do not want to apply current error mode here, since - * zend_make_printable_zval() uses output encoding converter. - * Temporarily set output encoding converter to escape offending - * chars with \uXXXX notation. - */ - zend_set_converter_error_mode(ZEND_U_CONVERTER(UG(output_encoding_conv)), ZEND_FROM_UNICODE, ZEND_CONV_ERROR_ESCAPE_JAVA); - TRACE_APPEND_CHR('\''); - if (Z_USTRLEN_PP(arg) > 15) { - TRACE_APPEND_USTRL(Z_USTRVAL_PP(arg), 15); - TRACE_APPEND_STR("...', "); - l_added = 15 + 6 + 1; /* +1 because of while (--l_added) */ - } else { - l_added = Z_USTRLEN_PP(arg); - TRACE_APPEND_USTRL(Z_USTRVAL_PP(arg), l_added); - TRACE_APPEND_STR("', "); - l_added += 3 + 1; - } - /* - * Reset output encoding converter error mode. - */ - zend_set_converter_error_mode(ZEND_U_CONVERTER(UG(output_encoding_conv)), ZEND_FROM_UNICODE, UG(from_error_mode)); - while (--l_added) { - if ((unsigned char)(*str)[*len - l_added] < 32) { - (*str)[*len - l_added] = '?'; - } - } - break; - } - case IS_BOOL: - if (Z_LVAL_PP(arg)) { - TRACE_APPEND_STR("true, "); - } else { - TRACE_APPEND_STR("false, "); - } - break; - case IS_RESOURCE: - TRACE_APPEND_STR("Resource id #"); - /* break; */ - case IS_LONG: { - long lval = Z_LVAL_PP(arg); - char s_tmp[MAX_LENGTH_OF_LONG + 1]; - int l_tmp = zend_sprintf(s_tmp, "%ld", lval); /* SAFE */ - TRACE_APPEND_STRL(s_tmp, l_tmp); - TRACE_APPEND_STR(", "); - break; - } - case IS_DOUBLE: { - double dval = Z_DVAL_PP(arg); - char *s_tmp; - int l_tmp; - - s_tmp = emalloc(MAX_LENGTH_OF_DOUBLE + EG(precision) + 1); - l_tmp = zend_sprintf(s_tmp, "%.*G", (int) EG(precision), dval); /* SAFE */ - TRACE_APPEND_STRL(s_tmp, l_tmp); - /* %G already handles removing trailing zeros from the fractional part, yay */ - efree(s_tmp); - TRACE_APPEND_STR(", "); - break; - } - case IS_ARRAY: - TRACE_APPEND_STR("Array, "); - break; - case IS_OBJECT: { - zval tmp; - zstr class_name; - zend_uint class_name_len; - int dup; - - TRACE_APPEND_STR("Object("); - - dup = zend_get_object_classname(*arg, &class_name, &class_name_len TSRMLS_CC); - - ZVAL_UNICODEL(&tmp, class_name.u, class_name_len, 1); - convert_to_string_with_converter(&tmp, ZEND_U_CONVERTER(UG(output_encoding_conv))); - TRACE_APPEND_STRL(Z_STRVAL(tmp), Z_STRLEN(tmp)); - zval_dtor(&tmp); - - if(!dup) { - efree(class_name.v); - } - - TRACE_APPEND_STR("), "); - break; - } - default: - break; - } - return ZEND_HASH_APPLY_KEEP; -} -/* }}} */ - - -static int mysqlnd_build_trace_string(zval **frame TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ -{ - char *s_tmp, **str; - int *len, *num; - long line; - HashTable *ht = Z_ARRVAL_PP(frame); - zval **file, **tmp; - uint * level; - - level = va_arg(args, uint *); - str = va_arg(args, char**); - len = va_arg(args, int*); - num = va_arg(args, int*); - - if (!*level) { - return ZEND_HASH_APPLY_KEEP; - } - --*level; - - s_tmp = emalloc(1 + MAX_LENGTH_OF_LONG + 1 + 1); - sprintf(s_tmp, "#%d ", (*num)++); - TRACE_APPEND_STRL(s_tmp, strlen(s_tmp)); - efree(s_tmp); - if (zend_ascii_hash_find(ht, "file", sizeof("file"), (void**)&file) == SUCCESS) { - if (zend_ascii_hash_find(ht, "line", sizeof("line"), (void**)&tmp) == SUCCESS) { - line = Z_LVAL_PP(tmp); - } else { - line = 0; - } - TRACE_APPEND_ZVAL(*file); - s_tmp = emalloc(MAX_LENGTH_OF_LONG + 2 + 1); - sprintf(s_tmp, "(%ld): ", line); - TRACE_APPEND_STRL(s_tmp, strlen(s_tmp)); - efree(s_tmp); - } else { - TRACE_APPEND_STR("[internal function]: "); - } - TRACE_APPEND_KEY("class"); - TRACE_APPEND_KEY("type"); - TRACE_APPEND_KEY("function"); - TRACE_APPEND_CHR('('); - if (zend_ascii_hash_find(ht, "args", sizeof("args"), (void**)&tmp) == SUCCESS) { - int last_len = *len; - zend_hash_apply_with_arguments(Z_ARRVAL_PP(tmp) TSRMLS_CC, (apply_func_args_t)mysqlnd_build_trace_args, 2, str, len); - if (last_len != *len) { - *len -= 2; /* remove last ', ' */ - } - } - TRACE_APPEND_STR(")\n"); - return ZEND_HASH_APPLY_KEEP; -} -/* }}} */ - - -#else /* PHP 5*/ - - -/* {{{ gettraceasstring() macros */ -#define TRACE_APPEND_CHR(chr) \ - *str = (char*)erealloc(*str, *len + 1 + 1); \ - (*str)[(*len)++] = chr - -#define TRACE_APPEND_STRL(val, vallen) \ - { \ - int l = vallen; \ - *str = (char*)erealloc(*str, *len + l + 1); \ - memcpy((*str) + *len, val, l); \ - *len += l; \ - } - -#define TRACE_APPEND_STR(val) \ - TRACE_APPEND_STRL(val, sizeof(val)-1) - -#define TRACE_APPEND_KEY(key) \ - if (zend_hash_find(ht, key, sizeof(key), (void**)&tmp) == SUCCESS) { \ - TRACE_APPEND_STRL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); \ - } - -/* }}} */ - - -static int mysqlnd_build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ -{ - char **str; - int *len; - - str = va_arg(args, char**); - len = va_arg(args, int*); - - /* the trivial way would be to do: - * conver_to_string_ex(arg); - * append it and kill the now tmp arg. - * but that could cause some E_NOTICE and also damn long lines. - */ - - switch (Z_TYPE_PP(arg)) { - case IS_NULL: - TRACE_APPEND_STR("NULL, "); - break; - case IS_STRING: { - int l_added; - TRACE_APPEND_CHR('\''); - if (Z_STRLEN_PP(arg) > 15) { - TRACE_APPEND_STRL(Z_STRVAL_PP(arg), 15); - TRACE_APPEND_STR("...', "); - l_added = 15 + 6 + 1; /* +1 because of while (--l_added) */ - } else { - l_added = Z_STRLEN_PP(arg); - TRACE_APPEND_STRL(Z_STRVAL_PP(arg), l_added); - TRACE_APPEND_STR("', "); - l_added += 3 + 1; - } - while (--l_added) { - if ((*str)[*len - l_added] < 32) { - (*str)[*len - l_added] = '?'; - } - } - break; - } - case IS_BOOL: - if (Z_LVAL_PP(arg)) { - TRACE_APPEND_STR("true, "); - } else { - TRACE_APPEND_STR("false, "); - } - break; - case IS_RESOURCE: - TRACE_APPEND_STR("Resource id #"); - /* break; */ - case IS_LONG: { - long lval = Z_LVAL_PP(arg); - char s_tmp[MAX_LENGTH_OF_LONG + 1]; - int l_tmp = zend_sprintf(s_tmp, "%ld", lval); /* SAFE */ - TRACE_APPEND_STRL(s_tmp, l_tmp); - TRACE_APPEND_STR(", "); - break; - } - case IS_DOUBLE: { - double dval = Z_DVAL_PP(arg); - char *s_tmp; - int l_tmp; - - s_tmp = emalloc(MAX_LENGTH_OF_DOUBLE + EG(precision) + 1); - l_tmp = zend_sprintf(s_tmp, "%.*G", (int) EG(precision), dval); /* SAFE */ - TRACE_APPEND_STRL(s_tmp, l_tmp); - /* %G already handles removing trailing zeros from the fractional part, yay */ - efree(s_tmp); - TRACE_APPEND_STR(", "); - break; - } - case IS_ARRAY: - TRACE_APPEND_STR("Array, "); - break; - case IS_OBJECT: { - char *class_name; - zend_uint class_name_len; - int dupl; - - TRACE_APPEND_STR("Object("); - - dupl = zend_get_object_classname(*arg, &class_name, &class_name_len TSRMLS_CC); - - TRACE_APPEND_STRL(class_name, class_name_len); - if (!dupl) { - efree(class_name); - } - - TRACE_APPEND_STR("), "); - break; - } - default: - break; - } - return ZEND_HASH_APPLY_KEEP; -} -/* }}} */ - -static int mysqlnd_build_trace_string(zval **frame TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ -{ - char *s_tmp, **str; - int *len, *num; - long line; - HashTable *ht = Z_ARRVAL_PP(frame); - zval **file, **tmp; - uint * level; - - level = va_arg(args, uint *); - str = va_arg(args, char**); - len = va_arg(args, int*); - num = va_arg(args, int*); - - if (!*level) { - return ZEND_HASH_APPLY_KEEP; - } - --*level; - - s_tmp = emalloc(1 + MAX_LENGTH_OF_LONG + 1 + 1); - sprintf(s_tmp, "#%d ", (*num)++); - TRACE_APPEND_STRL(s_tmp, strlen(s_tmp)); - efree(s_tmp); - if (zend_hash_find(ht, "file", sizeof("file"), (void**)&file) == SUCCESS) { - if (zend_hash_find(ht, "line", sizeof("line"), (void**)&tmp) == SUCCESS) { - line = Z_LVAL_PP(tmp); - } else { - line = 0; - } - s_tmp = emalloc(Z_STRLEN_PP(file) + MAX_LENGTH_OF_LONG + 4 + 1); - sprintf(s_tmp, "%s(%ld): ", Z_STRVAL_PP(file), line); - TRACE_APPEND_STRL(s_tmp, strlen(s_tmp)); - efree(s_tmp); - } else { - TRACE_APPEND_STR("[internal function]: "); - } - TRACE_APPEND_KEY("class"); - TRACE_APPEND_KEY("type"); - TRACE_APPEND_KEY("function"); - TRACE_APPEND_CHR('('); - if (zend_hash_find(ht, "args", sizeof("args"), (void**)&tmp) == SUCCESS) { - int last_len = *len; - zend_hash_apply_with_arguments(Z_ARRVAL_PP(tmp) TSRMLS_CC, (apply_func_args_t)mysqlnd_build_trace_args, 2, str, len); - if (last_len != *len) { - *len -= 2; /* remove last ', ' */ - } - } - TRACE_APPEND_STR(")\n"); - return ZEND_HASH_APPLY_KEEP; -} -/* }}} */ -#endif - - -PHPAPI char * mysqlnd_get_backtrace(uint max_levels, size_t * length TSRMLS_DC) -{ - zval *trace; - char *res = estrdup(""), **str = &res, *s_tmp; - int res_len = 0, *len = &res_len, num = 0; - if (max_levels == 0) { - max_levels = 99999; - } - - MAKE_STD_ZVAL(trace); - zend_fetch_debug_backtrace(trace, 0, 0 TSRMLS_CC); - - zend_hash_apply_with_arguments(Z_ARRVAL_P(trace) TSRMLS_CC, (apply_func_args_t)mysqlnd_build_trace_string, 4, &max_levels, str, len, &num); - zval_ptr_dtor(&trace); - - if (max_levels) { - s_tmp = emalloc(1 + MAX_LENGTH_OF_LONG + 7 + 1); - sprintf(s_tmp, "#%d {main}", num); - TRACE_APPEND_STRL(s_tmp, strlen(s_tmp)); - efree(s_tmp); - } - - res[res_len] = '\0'; - *length = res_len; - - return res; -} - - static struct st_mysqlnd_plugin_trace_log mysqlnd_plugin_trace_log_plugin = { { @@ -1880,6 +790,7 @@ static struct st_mysqlnd_plugin_trace_log mysqlnd_plugin_trace_log_plugin = } }; + /* {{{ mysqlnd_debug_trace_plugin_register */ void mysqlnd_debug_trace_plugin_register(TSRMLS_D) diff --git a/ext/mysqlnd/mysqlnd_debug.h b/ext/mysqlnd/mysqlnd_debug.h index 65560e5e5f..ff96d1e7c0 100644 --- a/ext/mysqlnd/mysqlnd_debug.h +++ b/ext/mysqlnd/mysqlnd_debug.h @@ -23,6 +23,7 @@ #ifndef MYSQLND_DEBUG_H #define MYSQLND_DEBUG_H +#include "mysqlnd_alloc.h" #include "zend_stack.h" struct st_mysqlnd_debug_methods @@ -71,11 +72,9 @@ struct st_mysqlnd_plugin_trace_log void mysqlnd_debug_trace_plugin_register(TSRMLS_D); -PHPAPI extern const char * mysqlnd_debug_std_no_trace_funcs[]; - PHPAPI MYSQLND_DEBUG * mysqlnd_debug_init(const char * skip_functions[] TSRMLS_DC); -PHPAPI char * mysqlnd_get_backtrace(uint max_levels, size_t * length TSRMLS_DC); +PHPAPI char * mysqlnd_get_backtrace(uint max_levels, size_t * length TSRMLS_DC); #if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 1400)) #ifdef PHP_WIN32 @@ -162,8 +161,6 @@ static inline void DBG_ENTER_EX(MYSQLND_DEBUG * dbg_obj, const char * const func #elif MYSQLND_DBG_ENABLED == 0 - - static inline void DBG_INF(const char * const msg) {} static inline void DBG_ERR(const char * const msg) {} static inline void DBG_INF_FMT(const char * const format, ...) {} @@ -174,62 +171,6 @@ static inline void DBG_ENTER(const char * const func_name) {} #endif - -#define MYSQLND_MEM_D TSRMLS_DC ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC -#define MYSQLND_MEM_C TSRMLS_CC ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC - -struct st_mysqlnd_allocator_methods -{ - void * (*m_emalloc)(size_t size MYSQLND_MEM_D); - void * (*m_pemalloc)(size_t size, zend_bool persistent MYSQLND_MEM_D); - void * (*m_ecalloc)(unsigned int nmemb, size_t size MYSQLND_MEM_D); - void * (*m_pecalloc)(unsigned int nmemb, size_t size, zend_bool persistent MYSQLND_MEM_D); - void * (*m_erealloc)(void *ptr, size_t new_size MYSQLND_MEM_D); - void * (*m_perealloc)(void *ptr, size_t new_size, zend_bool persistent MYSQLND_MEM_D); - void (*m_efree)(void *ptr MYSQLND_MEM_D); - void (*m_pefree)(void *ptr, zend_bool persistent MYSQLND_MEM_D); - void * (*m_malloc)(size_t size MYSQLND_MEM_D); - void * (*m_calloc)(unsigned int nmemb, size_t size MYSQLND_MEM_D); - void * (*m_realloc)(void *ptr, size_t new_size MYSQLND_MEM_D); - void (*m_free)(void *ptr MYSQLND_MEM_D); - char * (*m_pestrndup)(const char * const ptr, size_t size, zend_bool persistent MYSQLND_MEM_D); - char * (*m_pestrdup)(const char * const ptr, zend_bool persistent MYSQLND_MEM_D); -}; - -PHPAPI extern struct st_mysqlnd_allocator_methods mysqlnd_allocator; - - -PHPAPI void * _mysqlnd_emalloc(size_t size MYSQLND_MEM_D); -PHPAPI void * _mysqlnd_pemalloc(size_t size, zend_bool persistent MYSQLND_MEM_D); -PHPAPI void * _mysqlnd_ecalloc(unsigned int nmemb, size_t size MYSQLND_MEM_D); -PHPAPI void * _mysqlnd_pecalloc(unsigned int nmemb, size_t size, zend_bool persistent MYSQLND_MEM_D); -PHPAPI void * _mysqlnd_erealloc(void *ptr, size_t new_size MYSQLND_MEM_D); -PHPAPI void * _mysqlnd_perealloc(void *ptr, size_t new_size, zend_bool persistent MYSQLND_MEM_D); -PHPAPI void _mysqlnd_efree(void *ptr MYSQLND_MEM_D); -PHPAPI void _mysqlnd_pefree(void *ptr, zend_bool persistent MYSQLND_MEM_D); -PHPAPI void * _mysqlnd_malloc(size_t size MYSQLND_MEM_D); -PHPAPI void * _mysqlnd_calloc(unsigned int nmemb, size_t size MYSQLND_MEM_D); -PHPAPI void * _mysqlnd_realloc(void *ptr, size_t new_size MYSQLND_MEM_D); -PHPAPI void _mysqlnd_free(void *ptr MYSQLND_MEM_D); -PHPAPI char * _mysqlnd_pestrndup(const char * const ptr, size_t size, zend_bool persistent MYSQLND_MEM_D); -PHPAPI char * _mysqlnd_pestrdup(const char * const ptr, zend_bool persistent MYSQLND_MEM_D); - - -#define mnd_emalloc(size) mysqlnd_allocator.m_emalloc((size) MYSQLND_MEM_C) -#define mnd_pemalloc(size, pers) mysqlnd_allocator.m_pemalloc((size), (pers) MYSQLND_MEM_C) -#define mnd_ecalloc(nmemb, size) mysqlnd_allocator.m_ecalloc((nmemb), (size) MYSQLND_MEM_C) -#define mnd_pecalloc(nmemb, size, p) mysqlnd_allocator.m_pecalloc((nmemb), (size), (p) MYSQLND_MEM_C) -#define mnd_erealloc(ptr, new_size) mysqlnd_allocator.m_erealloc((ptr), (new_size) MYSQLND_MEM_C) -#define mnd_perealloc(ptr, new_size, p) mysqlnd_allocator.m_perealloc((ptr), (new_size), (p) MYSQLND_MEM_C) -#define mnd_efree(ptr) mysqlnd_allocator.m_efree((ptr) MYSQLND_MEM_C) -#define mnd_pefree(ptr, pers) mysqlnd_allocator.m_pefree((ptr), (pers) MYSQLND_MEM_C) -#define mnd_malloc(size) mysqlnd_allocator.m_malloc((size) MYSQLND_MEM_C) -#define mnd_calloc(nmemb, size) mysqlnd_allocator.m_calloc((nmemb), (size) MYSQLND_MEM_C) -#define mnd_realloc(ptr, new_size) mysqlnd_allocator.m_realloc((ptr), (new_size) MYSQLND_MEM_C) -#define mnd_free(ptr) mysqlnd_allocator.m_free((ptr) MYSQLND_MEM_C) -#define mnd_pestrndup(ptr, size, pers) mysqlnd_allocator.m_pestrndup((ptr), (size), (pers) MYSQLND_MEM_C) -#define mnd_pestrdup(ptr, pers) mysqlnd_allocator.m_pestrdup((ptr), (pers) MYSQLND_MEM_C) - #endif /* MYSQLND_DEBUG_H */ /* -- 2.40.0