diff options
author | Andrey Hristov <andrey@php.net> | 2010-04-06 13:28:23 +0000 |
---|---|---|
committer | Andrey Hristov <andrey@php.net> | 2010-04-06 13:28:23 +0000 |
commit | aa8f43fad9677cc73663bd1a675107d8a8f6af27 (patch) | |
tree | 2dd5e41395ca974dd6bcae3091efc816de22cd8b | |
parent | 5f11cd5693eeb658d3cbafd3fed7d51df296dafe (diff) | |
download | php-git-aa8f43fad9677cc73663bd1a675107d8a8f6af27.tar.gz |
Recommit with an Windows build fix:
Fix inconsistencies
- memory allocated with spprintf, or likes, outside of mysqlnd's
allocator functions should not be freed by the mysqlnd's allocator
(a wrapper around emalloc/malloc).
- memory allocated by the mysqlnd's allocator should only be freed
by it.
- add a mode to track memory usage (malloc/free)
-rw-r--r-- | ext/mysqlnd/mysqlnd.c | 35 | ||||
-rw-r--r-- | ext/mysqlnd/mysqlnd_debug.c | 231 | ||||
-rw-r--r-- | ext/mysqlnd/mysqlnd_enum_n_def.h | 14 | ||||
-rw-r--r-- | ext/mysqlnd/mysqlnd_net.c | 20 | ||||
-rw-r--r-- | ext/mysqlnd/mysqlnd_priv.h | 6 | ||||
-rw-r--r-- | ext/mysqlnd/mysqlnd_ps.c | 6 | ||||
-rw-r--r-- | ext/mysqlnd/mysqlnd_ps_codec.c | 6 | ||||
-rw-r--r-- | ext/mysqlnd/mysqlnd_statistics.c | 14 | ||||
-rw-r--r-- | ext/mysqlnd/mysqlnd_wireprotocol.c | 2 |
9 files changed, 186 insertions, 148 deletions
diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c index 6d313c161b..078d2e6afa 100644 --- a/ext/mysqlnd/mysqlnd.c +++ b/ext/mysqlnd/mysqlnd.c @@ -529,6 +529,7 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn, db = ""; db_len = 0; } + host_len = strlen(host); { char * transport = NULL; @@ -553,7 +554,7 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn, DBG_INF_FMT("transport=%s", transport); conn->scheme = mnd_pestrndup(transport, transport_len, conn->persistent); conn->scheme_len = transport_len; - efree(transport); + efree(transport); /* allocated by spprintf */ transport = NULL; } @@ -643,6 +644,7 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn, } } else { CONN_SET_STATE(conn, CONN_READY); + if (!self_alloced && saved_compression) { conn->net->compressed = TRUE; } @@ -662,16 +664,14 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn, conn->connect_or_select_db_len = db_len; if (!unix_socket) { - char *p; conn->host = mnd_pestrdup(host, conn->persistent); conn->host_len = strlen(conn->host); - spprintf(&p, 0, "%s via TCP/IP", conn->host); - if (conn->persistent) { - conn->host_info = mnd_pestrdup(p, 1); - mnd_efree(p); - } else { - conn->host_info = p; + { + char *p; + spprintf(&p, 0, "%s via TCP/IP", conn->host); + conn->host_info = mnd_pestrdup(p, conn->persistent); + efree(p); /* allocated by spprintf */ } } else { conn->unix_socket = mnd_pestrdup(socket, conn->persistent); @@ -693,10 +693,6 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn, SET_EMPTY_ERROR(conn->error_info); mysqlnd_local_infile_default(conn); - { - unsigned int buf_size = MYSQLND_G(net_cmd_buffer_size); /* this is long, cast to unsigned int*/ - conn->m->set_client_option(conn, MYSQLND_OPT_NET_CMD_BUFFER_SIZE, (char *)&buf_size TSRMLS_CC); - } MYSQLND_INC_CONN_STATISTIC_W_VALUE2(conn->stats, STAT_CONNECT_SUCCESS, 1, STAT_OPENED_CONNECTIONS, 1); if (reconnect) { @@ -707,6 +703,7 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn, } DBG_INF_FMT("connection_id=%llu", conn->thread_id); + #if PHP_MAJOR_VERSION >= 6 { unsigned int as_unicode = 1; @@ -715,7 +712,6 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn, DBG_INF("unicode set"); } #endif - if (conn->options.init_commands) { int current_command = 0; for (; current_command < conn->options.num_commands; ++current_command) { @@ -773,7 +769,7 @@ PHPAPI MYSQLND * mysqlnd_connect(MYSQLND * conn, unsigned int mysql_flags TSRMLS_DC) { - enum_func_status ret; + enum_func_status ret = FAIL; zend_bool self_alloced = FALSE; DBG_ENTER("mysqlnd_connect"); @@ -1139,7 +1135,7 @@ MYSQLND_METHOD(mysqlnd_conn, list_method)(MYSQLND *conn, const char *query, cons result = conn->m->store_result(conn TSRMLS_CC); } if (show_query != query) { - mnd_efree(show_query); + efree(show_query); /* allocated by spprintf */ } DBG_RETURN(result); } @@ -1225,7 +1221,7 @@ MYSQLND_METHOD(mysqlnd_conn, select_db)(MYSQLND * const conn, const char * const SET_ERROR_AFF_ROWS(conn); if (ret == PASS) { if (conn->connect_or_select_db) { - pefree(conn->connect_or_select_db, conn->persistent); + mnd_pefree(conn->connect_or_select_db, conn->persistent); } conn->connect_or_select_db = mnd_pestrndup(db, db_len, conn->persistent); conn->connect_or_select_db_len = db_len; @@ -1275,10 +1271,9 @@ MYSQLND_METHOD(mysqlnd_conn, stat)(MYSQLND *conn, char **message, unsigned int * if (FAIL == (ret = PACKET_READ(stats_header, conn))) { DBG_RETURN(FAIL); } - *message = stats_header->message; + /* will be freed by Zend, thus don't use the mnd_ allocator */ + *message = estrndup(stats_header->message, stats_header->message_len); *message_len = stats_header->message_len; - /* Ownership transfer */ - stats_header->message = NULL; PACKET_FREE(stats_header); DBG_INF(*message); @@ -1343,7 +1338,7 @@ MYSQLND_METHOD(mysqlnd_conn, set_charset)(MYSQLND * const conn, const char * con } else { conn->charset = charset; } - mnd_efree(query); + efree(query); /* allocated by spprintf */ DBG_INF(ret == PASS? "PASS":"FAIL"); DBG_RETURN(ret); diff --git a/ext/mysqlnd/mysqlnd_debug.c b/ext/mysqlnd/mysqlnd_debug.c index dcbe4bde87..d80ddc246c 100644 --- a/ext/mysqlnd/mysqlnd_debug.c +++ b/ext/mysqlnd/mysqlnd_debug.c @@ -656,24 +656,30 @@ PHPAPI void _mysqlnd_debug(const char * mode TSRMLS_DC) #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); + DBG_ENTER(mysqlnd_emalloc_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)); - ret = emalloc(size); - DBG_INF_FMT("after : %lu", zend_memory_usage(FALSE TSRMLS_CC)); - DBG_INF_FMT("size=%lu ptr=%p", size, ret); - if (MYSQLND_G(collect_memory_statistics)) { - MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_EMALLOC_COUNT, 1, STAT_MEM_EMALLOC_AMMOUNT, size); + ret = emalloc(REAL_SIZE(size)); + + DBG_INF_FMT("size=%lu ptr=%p", size, ret); + + if (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(ret); + DBG_RETURN(FAKE_PTR(ret)); } /* }}} */ @@ -682,29 +688,21 @@ void * _mysqlnd_emalloc(size_t size MYSQLND_MEM_D) void * _mysqlnd_pemalloc(size_t size, zend_bool persistent MYSQLND_MEM_D) { void *ret; + zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); DBG_ENTER(mysqlnd_pemalloc_name); DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); - if (persistent == FALSE) { - DBG_INF_FMT("before: %lu", zend_memory_usage(persistent TSRMLS_CC)); - } - - ret = pemalloc(size, persistent); - DBG_INF_FMT("size=%lu ptr=%p persistent=%d", size, ret, persistent); - if (persistent == FALSE) { - DBG_INF_FMT("after : %lu", zend_memory_usage(persistent TSRMLS_CC)); - } - - if (MYSQLND_G(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_AMMOUNT:STAT_MEM_EMALLOC_AMMOUNT; + ret = pemalloc(REAL_SIZE(size), persistent); + DBG_INF_FMT("size=%lu ptr=%p persistent=%d", size, ret, persistent); + if (collect_memory_statistics) { *(size_t *) ret = size; - + 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; MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(s1, 1, s2, size); } - DBG_RETURN(ret); + DBG_RETURN(FAKE_PTR(ret)); } /* }}} */ @@ -713,18 +711,20 @@ void * _mysqlnd_pemalloc(size_t size, zend_bool persistent MYSQLND_MEM_D) void * _mysqlnd_ecalloc(unsigned int nmemb, size_t size MYSQLND_MEM_D) { void *ret; + zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); 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)); - ret = ecalloc(nmemb, size); + ret = ecalloc(nmemb, REAL_SIZE(size)); DBG_INF_FMT("after : %lu", zend_memory_usage(FALSE TSRMLS_CC)); DBG_INF_FMT("size=%lu ptr=%p", size, ret); - if (MYSQLND_G(collect_memory_statistics)) { - MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_ECALLOC_COUNT, 1, STAT_MEM_ECALLOC_AMMOUNT, size); + if (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(ret); + DBG_RETURN(FAKE_PTR(ret)); } /* }}} */ @@ -733,26 +733,21 @@ void * _mysqlnd_ecalloc(unsigned int nmemb, size_t size MYSQLND_MEM_D) 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); DBG_ENTER(mysqlnd_pecalloc_name); DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); - if (persistent == FALSE) { - DBG_INF_FMT("before: %lu", zend_memory_usage(persistent TSRMLS_CC)); - } - ret = pecalloc(nmemb, size, persistent); + ret = pecalloc(nmemb, REAL_SIZE(size), persistent); DBG_INF_FMT("size=%lu ptr=%p", size, ret); - if (persistent == FALSE) { - DBG_INF_FMT("after : %lu", zend_memory_usage(persistent TSRMLS_CC)); - } - - if (MYSQLND_G(collect_memory_statistics)) { + if (collect_memory_statistics) { + *(size_t *) ret = size; enum mysqlnd_collected_stats s1 = persistent? STAT_MEM_CALLOC_COUNT:STAT_MEM_ECALLOC_COUNT; - enum mysqlnd_collected_stats s2 = persistent? STAT_MEM_CALLOC_AMMOUNT:STAT_MEM_ECALLOC_AMMOUNT; + enum mysqlnd_collected_stats s2 = persistent? STAT_MEM_CALLOC_AMOUNT:STAT_MEM_ECALLOC_AMOUNT; MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(s1, 1, s2, size); } - DBG_RETURN(ret); + DBG_RETURN(FAKE_PTR(ret)); } /* }}} */ @@ -761,19 +756,20 @@ void * _mysqlnd_pecalloc(unsigned int nmemb, size_t size, zend_bool persistent M 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 *) (ptr - sizeof(size_t)) : 0; 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 new_size=%lu", ptr, new_size); - DBG_INF_FMT("before: %lu", zend_memory_usage(FALSE TSRMLS_CC)); + DBG_INF_FMT("ptr=%p old_size=%lu, new_size=%lu", ptr, old_size, new_size); - ret = erealloc(ptr, new_size); + ret = erealloc(REAL_PTR(ptr), REAL_SIZE(new_size)); - DBG_INF_FMT("after : %lu", zend_memory_usage(FALSE TSRMLS_CC)); DBG_INF_FMT("new_ptr=%p", ret); - if (MYSQLND_G(collect_memory_statistics)) { - MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_EREALLOC_COUNT, 1, STAT_MEM_EREALLOC_AMMOUNT, new_size); + if (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(ret); + DBG_RETURN(FAKE_PTR(ret)); } /* }}} */ @@ -782,27 +778,23 @@ void * _mysqlnd_erealloc(void *ptr, size_t new_size MYSQLND_MEM_D) 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 *) (ptr - sizeof(size_t)) : 0; 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 new_size=%lu persist=%d", ptr, new_size, persistent); - if (persistent == FALSE) { - DBG_INF_FMT("before: %lu", zend_memory_usage(persistent TSRMLS_CC)); - } + DBG_INF_FMT("ptr=%p old_size=%lu new_size=%lu persist=%d", ptr, old_size, new_size, persistent); - ret = perealloc(ptr, new_size, persistent); + ret = perealloc(REAL_PTR(ptr), REAL_SIZE(new_size), persistent); DBG_INF_FMT("new_ptr=%p", ret); - if (persistent == FALSE) { - DBG_INF_FMT("after : %lu", zend_memory_usage(persistent TSRMLS_CC)); - } - MYSQLND_INC_GLOBAL_STATISTIC(persistent? STAT_MEM_REALLOC_COUNT:STAT_MEM_EREALLOC_COUNT); - if (MYSQLND_G(collect_memory_statistics)) { + if (collect_memory_statistics) { + *(size_t *) ret = new_size; enum mysqlnd_collected_stats s1 = persistent? STAT_MEM_REALLOC_COUNT:STAT_MEM_EREALLOC_COUNT; - enum mysqlnd_collected_stats s2 = persistent? STAT_MEM_REALLOC_AMMOUNT:STAT_MEM_EREALLOC_AMMOUNT; + enum mysqlnd_collected_stats s2 = persistent? STAT_MEM_REALLOC_AMOUNT:STAT_MEM_EREALLOC_AMOUNT; MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(s1, 1, s2, new_size); } - DBG_RETURN(ret); + DBG_RETURN(FAKE_PTR(ret)); } /* }}} */ @@ -810,15 +802,23 @@ void * _mysqlnd_perealloc(void *ptr, size_t new_size, zend_bool persistent MYSQL /* {{{ _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); - DBG_INF_FMT("before: %lu", zend_memory_usage(FALSE TSRMLS_CC)); - MYSQLND_INC_GLOBAL_STATISTIC(STAT_MEM_EFREE_COUNT); - efree(ptr); + if (ptr) { + if (collect_memory_statistics) { + free_amount = *(size_t *)(ptr - sizeof(size_t)); + DBG_INF_FMT("ptr=%p size=%u", ptr - sizeof(size_t), (unsigned int) free_amount); + } + efree(REAL_PTR(ptr)); + } - DBG_INF_FMT("after : %lu", zend_memory_usage(FALSE TSRMLS_CC)); + if (collect_memory_statistics) { + MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_EFREE_COUNT, 1, STAT_MEM_EFREE_AMOUNT, free_amount); + } DBG_VOID_RETURN; } /* }}} */ @@ -827,22 +827,23 @@ void _mysqlnd_efree(void *ptr MYSQLND_MEM_D) /* {{{ _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=%d", ptr, persistent); - if (persistent == FALSE) { - DBG_INF_FMT("before: %lu", zend_memory_usage(persistent TSRMLS_CC)); - } if (ptr) { - pefree(ptr, persistent); + if (collect_memory_statistics) { + free_amount = *(size_t *)(ptr - sizeof(size_t)); + DBG_INF_FMT("ptr=%p size=%u", ptr - sizeof(size_t), (unsigned int) free_amount); + } + pefree(REAL_PTR(ptr), persistent); } - if (persistent == FALSE) { - DBG_INF_FMT("after : %lu", zend_memory_usage(persistent TSRMLS_CC)); - } - if (MYSQLND_G(collect_memory_statistics)) { - MYSQLND_INC_GLOBAL_STATISTIC(persistent? STAT_MEM_FREE_COUNT:STAT_MEM_EFREE_COUNT); + 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; } @@ -852,16 +853,18 @@ void _mysqlnd_pefree(void *ptr, zend_bool persistent MYSQLND_MEM_D) void * _mysqlnd_malloc(size_t size MYSQLND_MEM_D) { void *ret; + zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); DBG_ENTER(mysqlnd_malloc_name); DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); - ret = malloc(size); + ret = malloc(REAL_SIZE(size)); DBG_INF_FMT("size=%lu ptr=%p", size, ret); - if (MYSQLND_G(collect_memory_statistics)) { - MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_MALLOC_COUNT, 1, STAT_MEM_MALLOC_AMMOUNT, size); + if (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(ret); + DBG_RETURN(FAKE_PTR(ret)); } /* }}} */ @@ -870,16 +873,18 @@ void * _mysqlnd_malloc(size_t size MYSQLND_MEM_D) void * _mysqlnd_calloc(unsigned int nmemb, size_t size MYSQLND_MEM_D) { void *ret; + zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); DBG_ENTER(mysqlnd_calloc_name); DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); - ret = calloc(nmemb, size); + ret = calloc(nmemb, REAL_SIZE(size)); DBG_INF_FMT("size=%lu ptr=%p", size, ret); - if (MYSQLND_G(collect_memory_statistics)) { - MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_CALLOC_COUNT, 1, STAT_MEM_CALLOC_AMMOUNT, size); + if (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(ret); + DBG_RETURN(FAKE_PTR(ret)); } /* }}} */ @@ -888,19 +893,21 @@ void * _mysqlnd_calloc(unsigned int nmemb, size_t size MYSQLND_MEM_D) void * _mysqlnd_realloc(void *ptr, size_t new_size MYSQLND_MEM_D) { void *ret; + zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); 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)); - ret = realloc(ptr, new_size); + ret = realloc(REAL_PTR(ptr), REAL_SIZE(new_size)); DBG_INF_FMT("new_ptr=%p", ret); - if (MYSQLND_G(collect_memory_statistics)) { - MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_REALLOC_COUNT, 1, STAT_MEM_REALLOC_AMMOUNT, new_size); + if (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(ret); + DBG_RETURN(FAKE_PTR(ret)); } /* }}} */ @@ -908,35 +915,58 @@ void * _mysqlnd_realloc(void *ptr, size_t new_size MYSQLND_MEM_D) /* {{{ _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); - free(ptr); + if (ptr) { + if (collect_memory_statistics) { + free_amount = *(size_t *)(ptr - sizeof(size_t)); + DBG_INF_FMT("ptr=%p size=%u", ptr - sizeof(size_t), (unsigned int) free_amount); + } + free(REAL_PTR(ptr)); + } - if (MYSQLND_G(collect_memory_statistics)) { - MYSQLND_INC_GLOBAL_STATISTIC(STAT_MEM_FREE_COUNT); + 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 = pestrndup(ptr, length, persistent); + 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 (MYSQLND_G(collect_memory_statistics)) { + if (collect_memory_statistics) { + *(size_t *) ret = length; MYSQLND_INC_GLOBAL_STATISTIC(persistent? STAT_MEM_STRNDUP_COUNT : STAT_MEM_ESTRNDUP_COUNT); } - DBG_RETURN(ret); + DBG_RETURN(FAKE_PTR(ret)); } /* }}} */ @@ -945,17 +975,26 @@ char * _mysqlnd_pestrndup(const char * const ptr, size_t length, zend_bool persi char * _mysqlnd_pestrdup(const char * const ptr, zend_bool persistent MYSQLND_MEM_D) { char * ret; + smart_str tmp_str = {0, 0, 0}; + 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); + DBG_INF_FMT("ptr=%p", ptr); + do { + smart_str_appendc(&tmp_str, *p); + } while (*p++); - ret = pestrdup(ptr, persistent); + ret = pemalloc(tmp_str.len + sizeof(size_t), persistent); + memcpy(FAKE_PTR(ret), tmp_str.c, tmp_str.len); - if (MYSQLND_G(collect_memory_statistics)) { + if (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(ret); + DBG_RETURN(FAKE_PTR(ret)); } /* }}} */ @@ -1008,11 +1047,11 @@ char * _mysqlnd_pestrdup(const char * const ptr, zend_bool persistent MYSQLND_ME zval copy; \ int use_copy; \ zend_make_printable_zval(*tmp, ©, &use_copy); \ - TRACE_APPEND_STRL(Z_STRVAL(copy), Z_STRLEN(copy)); \ - zval_dtor(©); \ + TRACE_APPEND_STRL(Z_STRVAL(copy), Z_STRLEN(copy)); \ + zval_dtor(©); \ } else { \ - TRACE_APPEND_STRL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); \ - } \ + TRACE_APPEND_STRL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); \ + } \ } /* }}} */ diff --git a/ext/mysqlnd/mysqlnd_enum_n_def.h b/ext/mysqlnd/mysqlnd_enum_n_def.h index 9b17f60fe6..4550bfd621 100644 --- a/ext/mysqlnd/mysqlnd_enum_n_def.h +++ b/ext/mysqlnd/mysqlnd_enum_n_def.h @@ -388,19 +388,21 @@ typedef enum mysqlnd_collected_stats STAT_STMT_CLOSE_EXPLICIT, STAT_STMT_CLOSE_IMPLICIT, STAT_MEM_EMALLOC_COUNT, - STAT_MEM_EMALLOC_AMMOUNT, + STAT_MEM_EMALLOC_AMOUNT, STAT_MEM_ECALLOC_COUNT, - STAT_MEM_ECALLOC_AMMOUNT, + STAT_MEM_ECALLOC_AMOUNT, STAT_MEM_EREALLOC_COUNT, - STAT_MEM_EREALLOC_AMMOUNT, + STAT_MEM_EREALLOC_AMOUNT, STAT_MEM_EFREE_COUNT, + STAT_MEM_EFREE_AMOUNT, STAT_MEM_MALLOC_COUNT, - STAT_MEM_MALLOC_AMMOUNT, + STAT_MEM_MALLOC_AMOUNT, STAT_MEM_CALLOC_COUNT, - STAT_MEM_CALLOC_AMMOUNT, + STAT_MEM_CALLOC_AMOUNT, STAT_MEM_REALLOC_COUNT, - STAT_MEM_REALLOC_AMMOUNT, + STAT_MEM_REALLOC_AMOUNT, STAT_MEM_FREE_COUNT, + STAT_MEM_FREE_AMOUNT, STAT_MEM_ESTRNDUP_COUNT, STAT_MEM_STRNDUP_COUNT, STAT_MEM_ESTRDUP_COUNT, diff --git a/ext/mysqlnd/mysqlnd_net.c b/ext/mysqlnd/mysqlnd_net.c index 41e1bd7fc1..1587acf482 100644 --- a/ext/mysqlnd/mysqlnd_net.c +++ b/ext/mysqlnd/mysqlnd_net.c @@ -121,14 +121,14 @@ MYSQLND_METHOD(mysqlnd_net, connect)(MYSQLND_NET * net, const char * const schem tv.tv_usec = 0; } + DBG_INF_FMT("calling php_stream_xport_create"); net->stream = php_stream_xport_create(scheme, scheme_len, streams_options, streams_flags, hashed_details, (net->options.timeout_connect) ? &tv : NULL, NULL /*ctx*/, errstr, errcode); - if (*errstr || !net->stream) { if (hashed_details) { - efree(hashed_details); + efree(hashed_details); /* allocated by spprintf */ } *errcode = CR_CONNECTION_ERROR; DBG_RETURN(FAIL); @@ -231,7 +231,7 @@ MYSQLND_METHOD(mysqlnd_net, send)(MYSQLND * const conn, char * const buf, size_t if (net->compressed == TRUE) { size_t comp_buf_size = MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE + MYSQLND_HEADER_SIZE + MIN(left, MYSQLND_MAX_PACKET_SIZE); DBG_INF_FMT("compress_buf_size=%d", comp_buf_size); - compress_buf = emalloc(comp_buf_size); + compress_buf = mnd_emalloc(comp_buf_size); } do { @@ -264,7 +264,7 @@ MYSQLND_METHOD(mysqlnd_net, send)(MYSQLND * const conn, char * const buf, size_t #if WHEN_WE_NEED_TO_CHECK_WHETHER_COMPRESSION_WORKS_CORRECTLY if (res == Z_OK) { size_t decompressed_size = left + MYSQLND_HEADER_SIZE; - zend_uchar * decompressed_data = malloc(decompressed_size); + zend_uchar * decompressed_data = mnd_malloc(decompressed_size); int error = net->m.decode(decompressed_data, decompressed_size, compress_buf + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE, payload_size); if (error == Z_OK) { int i; @@ -279,7 +279,7 @@ MYSQLND_METHOD(mysqlnd_net, send)(MYSQLND * const conn, char * const buf, size_t } else { DBG_INF("error decompressing"); } - free(decompressed_data); + mnd_free(decompressed_data); } #endif /* WHEN_WE_NEED_TO_CHECK_WHETHER_COMPRESSION_WORKS_CORRECTLY */ } else @@ -322,7 +322,7 @@ MYSQLND_METHOD(mysqlnd_net, send)(MYSQLND * const conn, char * const buf, size_t net->stream->chunk_size = old_chunk_size; if (compress_buf) { - efree(compress_buf); + mnd_efree(compress_buf); } DBG_RETURN(ret); } @@ -415,7 +415,7 @@ mysqlnd_read_compressed_packet_from_stream_and_fill_read_buffer(MYSQLND * conn, /* we need to decompress the data */ if (decompressed_size) { - compressed_data = emalloc(net_payload_size); + compressed_data = mnd_emalloc(net_payload_size); if (FAIL == conn->net->m.network_read(conn, compressed_data, net_payload_size TSRMLS_CC)) { ret = FAIL; goto end; @@ -435,7 +435,7 @@ mysqlnd_read_compressed_packet_from_stream_and_fill_read_buffer(MYSQLND * conn, } end: if (compressed_data) { - efree(compressed_data); + mnd_efree(compressed_data); } DBG_RETURN(ret); } @@ -688,7 +688,7 @@ mysqlnd_net_init(zend_bool persistent TSRMLS_DC) net->m.free_contents = MYSQLND_METHOD(mysqlnd_net, free_contents); { - unsigned int buf_size = MYSQLND_G(net_read_buffer_size); /* this is long, cast to unsigned int*/ + unsigned int buf_size = MYSQLND_G(net_cmd_buffer_size); /* this is long, cast to unsigned int*/ net->m.set_client_option(net, MYSQLND_OPT_NET_CMD_BUFFER_SIZE, (char *) &buf_size TSRMLS_CC); } DBG_RETURN(net); @@ -716,7 +716,7 @@ mysqlnd_net_free(MYSQLND_NET * const net TSRMLS_DC) if (pers) { php_stream_free(net->stream, PHP_STREAM_FREE_CLOSE_PERSISTENT | PHP_STREAM_FREE_RSRC_DTOR); } else { - php_stream_free(net->stream, PHP_STREAM_FREE_CLOSE); + php_stream_free(net->stream, PHP_STREAM_FREE_CLOSE); } net->stream = NULL; } diff --git a/ext/mysqlnd/mysqlnd_priv.h b/ext/mysqlnd/mysqlnd_priv.h index 7eb38b68dd..3ca37eaddb 100644 --- a/ext/mysqlnd/mysqlnd_priv.h +++ b/ext/mysqlnd/mysqlnd_priv.h @@ -93,10 +93,10 @@ #define SET_NEW_MESSAGE(buf, buf_len, message, len, persistent) \ {\ if ((buf)) { \ - pefree((buf), (persistent)); \ + mnd_pefree((buf), (persistent)); \ } \ if ((message)) { \ - (buf) = pestrndup((message), (len), (persistent)); \ + (buf) = mnd_pestrndup((message), (len), (persistent)); \ } else { \ buf = NULL; \ } \ @@ -106,7 +106,7 @@ #define SET_EMPTY_MESSAGE(buf, buf_len, persistent) \ {\ if ((buf)) { \ - pefree((buf), (persistent)); \ + mnd_pefree((buf), (persistent)); \ (buf) = NULL; \ } \ (buf_len) = 0; \ diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c index 563c018ad6..1d174ab853 100644 --- a/ext/mysqlnd/mysqlnd_ps.c +++ b/ext/mysqlnd/mysqlnd_ps.c @@ -599,7 +599,7 @@ MYSQLND_METHOD(mysqlnd_stmt, execute)(MYSQLND_STMT * const s TSRMLS_DC) not_bound, not_bound>1 ?"s":""); SET_STMT_ERROR(stmt, CR_PARAMS_NOT_BOUND, UNKNOWN_SQLSTATE, msg); if (msg) { - efree(msg); + efree(msg); /* allocated by spprintf */ } DBG_INF("FAIL"); DBG_RETURN(FAIL); @@ -2055,7 +2055,7 @@ MYSQLND_METHOD(mysqlnd_stmt, alloc_param_bind)(MYSQLND_STMT * const s TSRMLS_DC) { MYSQLND_STMT_DATA * stmt = s->data; DBG_ENTER("mysqlnd_stmt::alloc_param_bind"); - DBG_RETURN(pecalloc(stmt->param_count, sizeof(MYSQLND_PARAM_BIND), stmt->persistent)); + DBG_RETURN(mnd_pecalloc(stmt->param_count, sizeof(MYSQLND_PARAM_BIND), stmt->persistent)); } /* }}} */ @@ -2066,7 +2066,7 @@ MYSQLND_METHOD(mysqlnd_stmt, alloc_result_bind)(MYSQLND_STMT * const s TSRMLS_DC { MYSQLND_STMT_DATA * stmt = s->data; DBG_ENTER("mysqlnd_stmt::alloc_result_bind"); - DBG_RETURN(pecalloc(stmt->field_count, sizeof(MYSQLND_RESULT_BIND), stmt->persistent)); + DBG_RETURN(mnd_pecalloc(stmt->field_count, sizeof(MYSQLND_RESULT_BIND), stmt->persistent)); } /* }}} */ diff --git a/ext/mysqlnd/mysqlnd_ps_codec.c b/ext/mysqlnd/mysqlnd_ps_codec.c index dba749211c..5cc2f8bbdd 100644 --- a/ext/mysqlnd/mysqlnd_ps_codec.c +++ b/ext/mysqlnd/mysqlnd_ps_codec.c @@ -270,7 +270,7 @@ void ps_fetch_time(zval *zv, const MYSQLND_FIELD * const field, if (!as_unicode) { #endif ZVAL_STRINGL(zv, to, length, 1); - mnd_efree(to); + efree(to); /* allocated by spprintf */ #if PHP_MAJOR_VERSION >= 6 } else { ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_AUTOFREE); @@ -321,7 +321,7 @@ void ps_fetch_date(zval *zv, const MYSQLND_FIELD * const field, if (!as_unicode) { #endif ZVAL_STRINGL(zv, to, length, 1); - mnd_efree(to); + efree(to); /* allocated by spprintf */ #if PHP_MAJOR_VERSION >= 6 } else { ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_AUTOFREE); @@ -380,7 +380,7 @@ void ps_fetch_datetime(zval *zv, const MYSQLND_FIELD * const field, if (!as_unicode) { #endif ZVAL_STRINGL(zv, to, length, 1); - mnd_efree(to); + efree(to); /* allocated by spprintf */ #if PHP_MAJOR_VERSION >= 6 } else { ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_AUTOFREE); diff --git a/ext/mysqlnd/mysqlnd_statistics.c b/ext/mysqlnd/mysqlnd_statistics.c index 2e7665d8a7..8e34de4024 100644 --- a/ext/mysqlnd/mysqlnd_statistics.c +++ b/ext/mysqlnd/mysqlnd_statistics.c @@ -99,19 +99,21 @@ const MYSQLND_STRING mysqlnd_stats_values_names[STAT_LAST] = { STR_W_LEN("explicit_stmt_close") }, { STR_W_LEN("implicit_stmt_close") }, { STR_W_LEN("mem_emalloc_count") }, - { STR_W_LEN("mem_emalloc_ammount") }, + { STR_W_LEN("mem_emalloc_amount") }, { STR_W_LEN("mem_ecalloc_count") }, - { STR_W_LEN("mem_ecalloc_ammount") }, + { STR_W_LEN("mem_ecalloc_amount") }, { STR_W_LEN("mem_erealloc_count") }, - { STR_W_LEN("mem_erealloc_ammount") }, + { STR_W_LEN("mem_erealloc_amount") }, { STR_W_LEN("mem_efree_count") }, + { STR_W_LEN("mem_efree_amount") }, { STR_W_LEN("mem_malloc_count") }, - { STR_W_LEN("mem_malloc_ammount") }, + { STR_W_LEN("mem_malloc_amount") }, { STR_W_LEN("mem_calloc_count") }, - { STR_W_LEN("mem_calloc_ammount") }, + { STR_W_LEN("mem_calloc_amount") }, { STR_W_LEN("mem_realloc_count") }, - { STR_W_LEN("mem_realloc_ammount") }, + { STR_W_LEN("mem_realloc_amount") }, { STR_W_LEN("mem_free_count") }, + { STR_W_LEN("mem_free_amount") }, { STR_W_LEN("mem_estrndup_count") }, { STR_W_LEN("mem_strndup_count") }, { STR_W_LEN("mem_estndup_count") }, diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index 03f8550b28..dabd1b889e 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -542,7 +542,7 @@ php_mysqlnd_ok_read(void *_packet, MYSQLND *conn TSRMLS_DC) /* There is a message */ if (packet->header.size > p - buf && (i = php_mysqlnd_net_field_length(&p))) { - packet->message = estrndup((char *)p, MIN(i, buf_len - (p - begin))); + packet->message = mnd_pestrndup((char *)p, MIN(i, buf_len - (p - begin)), FALSE); packet->message_len = i; } else { packet->message = NULL; |