--- embedaddon/php/ext/mysqlnd/mysqlnd_debug.c 2012/02/21 23:47:58 1.1.1.1 +++ embedaddon/php/ext/mysqlnd/mysqlnd_debug.c 2012/05/29 12:34:41 1.1.1.2 @@ -18,15 +18,12 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_debug.c,v 1.1.1.1 2012/02/21 23:47:58 misho Exp $ */ +/* $Id: mysqlnd_debug.c,v 1.1.1.2 2012/05/29 12:34:41 misho Exp $ */ #include "php.h" #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,42 +33,7 @@ static const char * const mysqlnd_debug_default_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 MYSQLND_METHOD(mysqlnd_debug, open)(MYSQLND_DEBUG * self, zend_bool reopen) @@ -167,7 +129,7 @@ MYSQLND_METHOD(mysqlnd_debug, log)(MYSQLND_DEBUG * sel level_buffer[sizeof(level_buffer) - 1 ] = '\0'; } - message_line_len = spprintf(&message_line, 0, "%s%s%s%s%s%s%s%s\n", + message_line_len = mnd_sprintf(&message_line, 0, "%s%s%s%s%s%s%s%s\n", flags & MYSQLND_DEBUG_DUMP_PID? pid_buffer:"", flags & MYSQLND_DEBUG_DUMP_TIME? time_buffer:"", flags & MYSQLND_DEBUG_DUMP_FILE? file_buffer:"", @@ -176,7 +138,7 @@ MYSQLND_METHOD(mysqlnd_debug, log)(MYSQLND_DEBUG * sel pipe_buffer, type? type:"", message); ret = php_stream_write(self->stream, message_line, message_line_len)? PASS:FAIL; - efree(message_line); /* allocated by spprintf */ + mnd_sprintf_free(message_line); if (flags & MYSQLND_DEBUG_FLUSH) { self->m->close(self); self->m->open(self, TRUE); @@ -265,21 +227,20 @@ MYSQLND_METHOD(mysqlnd_debug, log_va)(MYSQLND_DEBUG *s level_buffer[sizeof(level_buffer) - 1 ] = '\0'; } - va_start(args, format); - vspprintf(&buffer, 0, format, args); + mnd_vsprintf(&buffer, 0, format, args); va_end(args); - message_line_len = spprintf(&message_line, 0, "%s%s%s%s%s%s%s%s\n", + message_line_len = mnd_sprintf(&message_line, 0, "%s%s%s%s%s%s%s%s\n", flags & MYSQLND_DEBUG_DUMP_PID? pid_buffer:"", flags & MYSQLND_DEBUG_DUMP_TIME? time_buffer:"", flags & MYSQLND_DEBUG_DUMP_FILE? file_buffer:"", flags & MYSQLND_DEBUG_DUMP_LINE? line_buffer:"", flags & MYSQLND_DEBUG_DUMP_LEVEL? level_buffer:"", pipe_buffer, type? type:"", buffer); - efree(buffer); + mnd_sprintf_free(buffer); ret = php_stream_write(self->stream, message_line, message_line_len)? PASS:FAIL; - efree(message_line); /* allocated by spprintf */ + mnd_sprintf_free(message_line); if (flags & MYSQLND_DEBUG_FLUSH) { self->m->close(self); @@ -538,7 +499,7 @@ MYSQLND_METHOD(mysqlnd_debug, free)(MYSQLND_DEBUG * se zend_stack_destroy(&self->call_time_stack); zend_hash_destroy(&self->not_filtered_functions); zend_hash_destroy(&self->function_profiles); - efree(self); + free(self); return PASS; } /* }}} */ @@ -761,7 +722,7 @@ MYSQLND_CLASS_METHODS_END; PHPAPI MYSQLND_DEBUG * mysqlnd_debug_init(const char * skip_functions[] TSRMLS_DC) { - MYSQLND_DEBUG *ret = ecalloc(1, sizeof(MYSQLND_DEBUG)); + MYSQLND_DEBUG *ret = calloc(1, sizeof(MYSQLND_DEBUG)); #ifdef ZTS ret->TSRMLS_C = TSRMLS_C; #endif @@ -783,7 +744,7 @@ mysqlnd_debug_init(const char * skip_functions[] TSRML /* {{{ _mysqlnd_debug */ PHPAPI void _mysqlnd_debug(const char * mode TSRMLS_DC) { -#ifdef PHP_DEBUG +#if PHP_DEBUG MYSQLND_DEBUG *dbg = MYSQLND_G(dbg); if (!dbg) { MYSQLND_G(dbg) = dbg = mysqlnd_debug_init(mysqlnd_debug_std_no_trace_funcs TSRMLS_CC); @@ -805,1056 +766,38 @@ 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) +static struct st_mysqlnd_plugin_trace_log mysqlnd_plugin_trace_log_plugin = { - 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); - -#ifdef PHP_DEBUG - /* -1 is also "true" */ - if (*threshold) { -#endif - ret = emalloc(REAL_SIZE(size)); -#ifdef 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); - -#ifdef PHP_DEBUG - /* -1 is also "true" */ - if (*threshold) { -#endif - ret = pemalloc(REAL_SIZE(size), persistent); -#ifdef 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)); - -#ifdef PHP_DEBUG - /* -1 is also "true" */ - if (*threshold) { -#endif - ret = ecalloc(nmemb, REAL_SIZE(size)); -#ifdef 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); - -#ifdef PHP_DEBUG - /* -1 is also "true" */ - if (*threshold) { -#endif - ret = pecalloc(nmemb, REAL_SIZE(size), persistent); -#ifdef 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); - -#ifdef PHP_DEBUG - /* -1 is also "true" */ - if (*threshold) { -#endif - ret = erealloc(REAL_PTR(ptr), REAL_SIZE(new_size)); -#ifdef 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); - -#ifdef PHP_DEBUG - /* -1 is also "true" */ - if (*threshold) { -#endif - ret = perealloc(REAL_PTR(ptr), REAL_SIZE(new_size), persistent); -#ifdef 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); - -#ifdef PHP_DEBUG - /* -1 is also "true" */ - if (*threshold) { -#endif - ret = malloc(REAL_SIZE(size)); -#ifdef 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); - -#ifdef PHP_DEBUG - /* -1 is also "true" */ - if (*threshold) { -#endif - ret = calloc(nmemb, REAL_SIZE(size)); -#ifdef 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)); - -#ifdef PHP_DEBUG - /* -1 is also "true" */ - if (*threshold) { -#endif - ret = realloc(REAL_PTR(ptr), REAL_SIZE(new_size)); -#ifdef 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++; + MYSQLND_PLUGIN_API_VERSION, + "debug_trace", + MYSQLND_VERSION_ID, + MYSQLND_VERSION, + "PHP License 3.01", + "Andrey Hristov , Ulf Wendel , Georg Richter ", + { + NULL, /* no statistics , will be filled later if there are some */ + NULL, /* no statistics */ + }, + { + NULL /* plugin shutdown */ } - *dest = '\0'; + }, + {/* methods */ + mysqlnd_debug_init, + mysqlnd_get_backtrace } - - 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) +/* {{{ mysqlnd_debug_trace_plugin_register */ +void +mysqlnd_debug_trace_plugin_register(TSRMLS_D) { - 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; + mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_plugin_trace_log_plugin TSRMLS_CC); } /* }}} */ - -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: