From 1a43eb0aeafdacd93ee6ab81300abdc79caa7df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Wed, 29 Jul 2015 23:18:23 +0000 Subject: [PATCH] Bugfixes - memory leak - other errors as reported by valgrind --- .../mariadb-client-library/libmariadb.c.patch | 18 +++++++------ include/MySQL_Protocol.h | 3 +++ lib/MySQL_Protocol.cpp | 2 +- lib/MySQL_Thread.cpp | 25 ++++++++++++------- lib/mysql_connection.cpp | 7 ++++-- lib/mysql_data_stream.cpp | 6 +++++ 6 files changed, 41 insertions(+), 20 deletions(-) diff --git a/deps/mariadb-client-library/libmariadb.c.patch b/deps/mariadb-client-library/libmariadb.c.patch index c8b97bee6..b6d013d1f 100644 --- a/deps/mariadb-client-library/libmariadb.c.patch +++ b/deps/mariadb-client-library/libmariadb.c.patch @@ -1,15 +1,17 @@ -@@ -2192,6 +2192,14 @@ +@@ -2192,6 +2192,16 @@ my_free(mysql->options.extension->ssl_crlpath, MYF(MY_ALLOW_ZERO_PTR)); if(hash_inited(&mysql->options.extension->connect_attrs)) hash_free(&mysql->options.extension->connect_attrs); + { -+ struct mysql_async_context *ctxt; -+ if ((ctxt = mysql->options.extension->async_context) != 0) -+ { -+ my_context_destroy(&ctxt->async_context); -+ my_free((gptr)ctxt, MYF(0)); -+ } -+ } ++ struct mysql_async_context *ctxt; ++ if ((ctxt = mysql->options.extension->async_context) != 0) { ++ if (ctxt->active==0) { ++ my_context_destroy(&ctxt->async_context); ++ my_free((gptr)ctxt, MYF(0)); ++ mysql->options.extension->async_context=NULL; ++ } ++ } ++ } } my_free((gptr)mysql->options.extension, MYF(MY_ALLOW_ZERO_PTR)); /* clear all pointer */ diff --git a/include/MySQL_Protocol.h b/include/MySQL_Protocol.h index 2c3019cde..88c03c1a8 100644 --- a/include/MySQL_Protocol.h +++ b/include/MySQL_Protocol.h @@ -29,6 +29,9 @@ class MySQL_Protocol { MySQL_Prepared_Stmt_info *current_PreStmt; uint16_t prot_status; MySQL_Data_Stream *get_myds() { return *myds; } + MySQL_Protocol() { + prot_status=0; + } void init(MySQL_Data_Stream **, MySQL_Connection_userinfo *, MySQL_Session *); int pkt_handshake_client(unsigned char *, unsigned int); int parse_mysql_pkt(PtrSize_t *, MySQL_Data_Stream *); diff --git a/lib/MySQL_Protocol.cpp b/lib/MySQL_Protocol.cpp index d16da8b0e..303843446 100644 --- a/lib/MySQL_Protocol.cpp +++ b/lib/MySQL_Protocol.cpp @@ -457,7 +457,7 @@ void MySQL_Protocol::init(MySQL_Data_Stream **__myds, MySQL_Connection_userinfo userinfo=__userinfo; sess=__sess; current_PreStmt=NULL; - prot_status=0; +// prot_status=0; } int MySQL_Protocol::pkt_handshake_client(unsigned char *pkt, unsigned int length) { diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index 9cb1981d7..4e12da0a0 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -1035,19 +1035,25 @@ void MySQL_Thread::run() { num_idles=MyHGM->get_multiple_idle_connections(-1, curtime-mysql_thread___ping_interval_server*1000, my_idle_conns, SESSIONS_FOR_CONNECTIONS_HANDLER); for (i=0; imyconn=mc; - myds->attach_connection(mc); - myds->assign_fd_from_mysql_conn(); - myds->myds_type=MYDS_BACKEND; + // myds->attach_connection(mc); + // myds->assign_fd_from_mysql_conn(); + // myds->myds_type=MYDS_BACKEND; //MySQL_Session *sess=(MySQL_Session *)mysql_sessions_connections_handler->index(i); MySQL_Session *sess=new MySQL_Session(); - myds->sess=sess; - myds->init(); - my_idle_myds[i]=myds; + // myds->sess=sess; + // myds->init(); + // my_idle_myds[i]=myds; sess->mybe=sess->find_or_create_backend(mc->parent->myhgc->hid); - sess->mybe->server_myds=myds; + // sess->mybe->server_myds=myds; + + myds=sess->mybe->server_myds; + myds->attach_connection(mc); + myds->assign_fd_from_mysql_conn(); + myds->myds_type=MYDS_BACKEND; + sess->to_process=1; myds->wait_until=curtime+mysql_thread___ping_timeout_server*1000; // max_timeout // sess->status=WAITING_SERVER_DATA; @@ -1095,7 +1101,8 @@ void MySQL_Thread::run() { } for (n = 0; n < mypolls.len; n++) { - MySQL_Data_Stream *myds=mypolls.myds[n]; + MySQL_Data_Stream *myds=NULL; + myds=mypolls.myds[n]; mypolls.fds[n].revents=0; if (myds && myds->wait_until) { if (myds->wait_until > curtime) { diff --git a/lib/mysql_connection.cpp b/lib/mysql_connection.cpp index 142866a98..8b1d39d4a 100644 --- a/lib/mysql_connection.cpp +++ b/lib/mysql_connection.cpp @@ -62,7 +62,7 @@ uint64_t MySQL_Connection_userinfo::compute_hash() { #define _COMPUTE_HASH_DEL2_ "-8k7jrhtrgJHRgrefgreyhtRFewg6-" l+=strlen(_COMPUTE_HASH_DEL1_); l+=strlen(_COMPUTE_HASH_DEL2_); - char *buf=(char *)malloc(l); + char *buf=(char *)malloc(l+1); l=0; if (username) { strcpy(buf+l,username); @@ -108,7 +108,10 @@ void MySQL_Connection_userinfo::set(MySQL_Connection_userinfo *ui) { bool MySQL_Connection_userinfo::set_schemaname(char *_new, int l) { if ((schemaname==NULL) || (strncmp(_new,schemaname,l))) { - if (schemaname) free(schemaname); + if (schemaname) { + free(schemaname); + schemaname=NULL; + } if (l) { schemaname=(char *)malloc(l+1); memcpy(schemaname,_new,l); diff --git a/lib/mysql_data_stream.cpp b/lib/mysql_data_stream.cpp index 9b9749fd5..2535fc0bb 100644 --- a/lib/mysql_data_stream.cpp +++ b/lib/mysql_data_stream.cpp @@ -559,6 +559,7 @@ int MySQL_Data_Stream::array2buffer() { //unsigned int idx=0; bool cont=true; while (cont) { + VALGRIND_DISABLE_ERROR_REPORTING; if (queue_available(queueOUT)==0) return ret; if (queueOUT.partial==0) { // read a new packet //if (PSarrayOUT->len-idx) { @@ -568,11 +569,14 @@ int MySQL_Data_Stream::array2buffer() { l_free(queueOUT.pkt.size,queueOUT.pkt.ptr); queueOUT.pkt.ptr=NULL; } + VALGRIND_ENABLE_ERROR_REPORTING; if (myconn->get_status_compression()==true) { proxy_debug(PROXY_DEBUG_PKT_ARRAY, 5, "DataStream: %p -- Compression enabled\n", this); generate_compressed_packet(); // it is copied directly into queueOUT.pkt } else { + VALGRIND_DISABLE_ERROR_REPORTING; PSarrayOUT->remove_index(0,&queueOUT.pkt); + VALGRIND_ENABLE_ERROR_REPORTING; // this is a special case, needed because compression is enabled *after* the first OK if (DSS==STATE_CLIENT_AUTH_OK) { DSS=STATE_SLEEP; @@ -602,7 +606,9 @@ int MySQL_Data_Stream::array2buffer() { } } int b= ( queue_available(queueOUT) > (queueOUT.pkt.size - queueOUT.partial) ? (queueOUT.pkt.size - queueOUT.partial) : queue_available(queueOUT) ); + VALGRIND_DISABLE_ERROR_REPORTING; memcpy(queue_w_ptr(queueOUT), (unsigned char *)queueOUT.pkt.ptr + queueOUT.partial, b); + VALGRIND_ENABLE_ERROR_REPORTING; queue_w(queueOUT,b); proxy_debug(PROXY_DEBUG_PKT_ARRAY, 5, "DataStream: %p -- Copied %d bytes into send buffer\n", this, b); queueOUT.partial+=b;