Description:
Hi All!
I'm making some changes in mysql client library for my needs
(may be I talk with proposal about them in mail list later) and
I found some strange behavior in mysql console client.
After issuing command 'use somedatabase' in client with debugging turned on
I have report about leaked memory in 100% of cases.
How to repeat:
To reproduce this just build mysql with configure option
'--with-debug=full' (I'm using MySQL version 4.1.3,
operating system FreeBSD 5.2.1-RELEASE,
MySQL build from ports, just tweaked Makefile to turn debugging)
and then run client:
-------------------------------------------------------------------------
$ mysql -p test --debug=full
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 17 to server version: 4.1.3-beta-log
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> use test;
Database changed
mysql> Bye
User time 0.01, System time 0.00
Maximum resident set size 2340, Integral resident set size 96
Non-physical pagefaults 227, Physical pagefaults 2, Swaps 0
Blocks in 14 out 1, Messages in 4 out 16, Signals 0
Voluntary context switches 28, Involuntary context switches 17
Warning: Not freed memory segments: 1
Warning: Memory that was not free'ed (5 bytes):
5 bytes at 0x00805b0d8, allocated at line 892 in 'mysql.cc'
-------------------------------------------------------------------------
Look, 5 bytes, exact size of word 'test' + zero byte.
Suggested fix:
When analyzing function com_use() in client/mysql.cc
I found strange code, it sets current_db pointer to zero
before starting to check for current database and calling mysql_selectd_db().
No calls for my_free() found before.
Here it is:
-------------------------------------------------------------------------
...
/*
We need to recheck the current database, because it may change
under our feet, for example if DROP DATABASE or RENAME DATABASE
(latter one not yet available by the time the comment was written)
*/
current_db= 0; // Let's reset current_db, assume it's gone <<<<==================
/*
We don't care about in case of an error below because current_db
was just set to 0.
*/
if (!mysql_query(&mysql, "SELECT DATABASE()") &&
(res= mysql_use_result(&mysql)))
{
row= mysql_fetch_row(res);
if (row[0] &&
(!current_db || cmp_database(charset_info, current_db, row[0])))
...
-------------------------------------------------------------------------
It doesn't seems to be good to drop pointer to string at start.
Maybe it's better to place 'my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));'
before this line? :-\ But, in such case I'm cannot understand what does
later code, with checks like '!current_db || cmp_database(charset_info, current_db, row[0]'...
current_db is set to 0, so for what we are checking???
I'm just looked in sources of 4.1.4a, this code was unchanged.
Can MySQL staff look at this, please?
P.S. Sorry if my english is poor. :-(