| Bug #62245 | mysql_stmt_prepare() would lead to memory leaks in libmysqld | ||
|---|---|---|---|
| Submitted: | 24 Aug 2011 5:20 | Modified: | 20 Feb 2012 18:46 |
| Reporter: | Qi Zhou | Email Updates: | |
| Status: | Verified | Impact on me: | |
| Category: | MySQL Server: Embedded Library ( libmysqld ) | Severity: | S2 (Serious) |
| Version: | 5.5.15, 5.5.22 | OS: | Any |
| Assigned to: | CPU Architecture: | Any | |
| Tags: | mysql_stmt_prepare mem leaks | ||
[20 Feb 2012 18:46]
Sveta Smirnova
Thank you for the report. Verified as described: ==2590== 2,064 bytes in 1 blocks are definitely lost in loss record 3 of 3 ==2590== at 0x4A05FDE: malloc (vg_replace_malloc.c:236) ==2590== by 0x5462A9: my_malloc (my_malloc.c:38) ==2590== by 0x532974: init_alloc_root (my_alloc.c:63) ==2590== by 0x43AA7F: mysql_stmt_init (libmysql.c:1500) ==2590== by 0x437A43: main (bug62136.cpp:53) To repeat compile test case from bug 62136, then run it as: valgrind --leak-check=full ./bug62136
[20 Feb 2012 18:49]
Sveta Smirnova
Problem is not repeatable without embedded server.

Description: mysql_stmt_prepare() would call emb_read_prepare_result(), there is a bug will lead to memory leak: 235 static my_bool emb_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt) 236 { 237 THD *thd= (THD*) mysql->thd; 238 MYSQL_DATA *res; 239 240 stmt->stmt_id= thd->client_stmt_id; 241 stmt->param_count= thd->client_param_count; 242 stmt->field_count= 0; 243 mysql->warning_count= thd->warning_info->statement_warn_count(); 244 245 if (thd->first_data) 246 { 247 if (emb_read_query_result(mysql)) 248 return 1; 249 stmt->field_count= mysql->field_count; 250 mysql->status= MYSQL_STATUS_READY; 251 res= thd->cur_data; 252 thd->cur_data= NULL; 253 if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT)) 254 mysql->server_status|= SERVER_STATUS_IN_TRANS; 255 256 stmt->fields= mysql->fields; 257 stmt->mem_root= res->alloc; 258 mysql->fields= NULL; 259 my_free(res); 260 } 261 262 return 0; 263 } note line 257, the old mem_root is not freed yet. ( although you called: free_root(&stmt->mem_root, MYF(MY_KEEP_PREALLOC)); in the mysql_stmt_prepare(), but the prealloced memory would be reserved. ) How to repeat: you can run any case using mysql_stmt_prepare() and check it with valgrind.