MySQL++ Memory leak

MySQL++ Memory leak

am 13.11.2002 15:14:32 von kerzum

--------------Boundary-00=_88QIYM22TXT8CFZ3UP9T
Content-Type: text/plain;
charset="koi8-r"
Content-Transfer-Encoding: 8bit


Background:
MySQL++ ( libsqlplus ) is a pretty nice official C++ styled mysql client
library wrapper of libmysqlclient. It offers STL-style C++ interface and is
designed with an effort of generic programming style. It should be a really
excellent choise if only it had not a MEMORY LEAK problem.
http://www.mysql.com/downloads/api-mysql++.html

Investigation:
As this library is commonly used to develop a CGI C++ application problem is
not so crytical. CGI process lives just a few seconds and then dies, all
memory it have been using is deallocated by the system. I've fortunely found
this bug developing apache mod_rewrite program map application that should
stay alive all the apache lifetime. It cannot be restarted without httpd
restart, and if it craches it crashes apache too =(

I use a little subset of mysql++ capabilities
- Connection
- Query ( only Query::store )
- Result
Memory leak I discovered is located somewhere in Result::operator= and is
available only after update;
Proof of concept code is supplied.
It leaks 1 Mb of memory in 10 seconds executing about 12000 updates
I use Intel celeron 333, 2.4.18 linux kernel on late slackware distibution.
MySQL++ 1.7.9 built from source, no __USLC__ conditional defined

Workaround:
Recreating Result object each query elminates this problem.
But we still hope on MySQL++ development team, aint we =?

Links:
Note that I have been using just a little subset of MySQL++, further memory
leaks may follow.
mailing.database.myodbc and mailing.database.mysql group has several repots
about -- have a look at them
( Google->groups search result on 'mysql++ memory leak' )
--
http://groups.google.com.ru/groups?q=mysql%2B%2B+memory+leak &hl=ru&lr=&ie=UTF-8&inlang=ru&selm=a9p6vn%242oci%241%40FreeB SD.csie.NCTU.edu.tw&rnum=3
http://groups.google.com.ru/groups?q=mysql%2B%2B+memory+leak &hl=ru&lr=&ie=UTF-8&inlang=ru&selm=2ed0f107.0203200439.2b4ef 27a%40posting.google.com&rnum=2

--

Sincerely yours
Peter Kerzum


--------------Boundary-00=_88QIYM22TXT8CFZ3UP9T
Content-Type: text/x-c++;
charset="koi8-r";
name="leak.cc"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="leak.cc"

#include
#include
using namespace std;

#define DBNAME "test"
#define DBHOST "localhost"
#define DBUSER "root"
#define DBPW ""

const string dbname(DBNAME);
const string dbhost(DBHOST);
const string dbuser(DBUSER);
const string dbpw(DBPW);

#define dlog cerr
Connection* con=0;
Result res;

//Result *res=0;

void sql(const char* q)
{
// dlog << "[ DB ] Query sent: " << q << endl;
try {
Query query = con->query();

// Use of dynamically allocated and manually cleaned Result
// will eliminate memory leak

// if(res) delete res;
// res=new Result();
// *res=query.store(q);

// MEMORY LEAK
res=query.store(q);

}
catch(BadQuery &e)
{
dlog << "[ DB ] MySQLLow -- BadQuery: " << e.error << endl;
throw;
}
catch(exception& e)
{
dlog << "[ DB ] MySQLLow -- exception: " << e.what() << endl;
throw;
}
catch(...)
{
dlog << "[ DB ] MySQLLow -- exception: ?" << endl;
throw;
}
}

void connect(void)
{
dlog << "[ DB ] Connecting to database: " << dbname << endl;

try {
con=new Connection(use_exceptions);
con->connect("",dbhost.c_str(),dbuser.c_str(),dbpw.c_str());
try {
con->select_db(dbname);
} catch (BadQuery &er) {
con->create_db(dbname.c_str());
con->select_db(dbname.c_str());
}
}
catch(BadQuery &e)
{
dlog << "MySQLLow -- BadQuery: " << e.error << endl;
throw;
}
catch(exception& e)
{
dlog << "MySQLLow -- exception: " << e.what() << endl;
throw;
}

}

int main(void)
{
connect();
int i=0;
while(true)
{
sql("SELECT * FROM a");

// comment out this line to eliminate memory leak
sql("UPDATE a SET i=i+1");
dlog << '.';
}
}


--------------Boundary-00=_88QIYM22TXT8CFZ3UP9T--

Re: MySql++ memory leak

am 14.11.2002 07:15:39 von Benjamin Pflugmann

Hello.

On Wed 2002-11-13 at 17:19:20 +0300, kerzum@mail.ru wrote:
> >Description:
> I use a little subset of mysql++ capabilities
> - Connection
> - Query ( only Query::store )
> - Result
> Memory leak I discovered is located somewhere in Result::operator= and is
> available only after update;

Well, using a result set after an UPDATE query, which produces no
resulting rows doesn't makes much sense. I expected it to be not
supported by the interface at all. The docs are a bit scarce with info
about that, IMHO. But obviously the underlying C interface explicitly
allows it.

> Proof of concept code is supplied.
> It leaks 1 Mb of memory in 10 seconds executing about 12000 updates
> I use Intel celeron 333, 2.4.18 linux kernel on late slackware distibution.
> MySQL++ 1.7.9 built from source, no __USLC__ conditional defined

The patch below should fix that. Not tested, because I don't use
MySQL++. The problem was that Result::operator= does not correctly
free resources when the instance to be assigned is an "null"
instance. You get such a "null" instance, e.g. if you request the
result of an UPDATE or when using the default constructor.

Bye,

Benjamin.

PS: Please don't cross-post next time.



--- result_orig.cc 2002-11-14 03:19:28.000000000 +0100
+++ result.cc 2002-11-14 03:20:16.000000000 +0100
@@ -20,11 +20,11 @@
}

void ResUse::copy(const ResUse& other) {
+ if (initialized)
+ purge();
if (!other.mysql_res) {
mysql_res=0; _types=0; _names=0; return;
}
- if (initialized)
- purge();
throw_exceptions = other.throw_exceptions;
mysql_res = other.mysql_res;
_fields = other._fields;



[...]
> Result res;
>
> void sql(const char* q)
> {
> // dlog << "[ DB ] Query sent: " << q << endl;
> try {
> Query query = con->query();
>
> // Use of dynamically allocated and manually cleaned Result
> // will eliminate memory leak
>
> // if(res) delete res;
> // res=new Result();
> // *res=query.store(q);
>
> // MEMORY LEAK
> res=query.store(q);
>
> }
[...]
> }
>
> int main(void)
> {
> connect();
> int i=0;
> while(true)
> {
> sql("SELECT * FROM a");
>
> // comment out this line to eliminate memory leak
> sql("UPDATE a SET i=i+1");
> dlog << '.';
> }
> }
[...]

--
benjamin-mysql@pflugmann.de

------------------------------------------------------------ ---------
Before posting, please check:
http://www.mysql.com/manual.php (the manual)
http://lists.mysql.com/ (the list archive)

To request this thread, e-mail bugs-thread12984@lists.mysql.com
To unsubscribe, e-mail

Re: MySql++ memory leak

am 14.11.2002 13:52:11 von Sinisa Milivojevic

Benjamin Pflugmann writes:
> Hello.
>
> On Wed 2002-11-13 at 17:19:20 +0300, kerzum@mail.ru wrote:
>
> Well, using a result set after an UPDATE query, which produces no
> resulting rows doesn't makes much sense. I expected it to be not
> supported by the interface at all. The docs are a bit scarce with info
> about that, IMHO. But obviously the underlying C interface explicitly
> allows it.
>
> The patch below should fix that. Not tested, because I don't use
> MySQL++. The problem was that Result::operator= does not correctly
> free resources when the instance to be assigned is an "null"
> instance. You get such a "null" instance, e.g. if you request the
> result of an UPDATE or when using the default constructor.
>
> Bye,
>
> Benjamin.
>
> PS: Please don't cross-post next time.

Hi!

Thank you for your note.

Can I get a full source code of the example which demonstrates this
suspicious memory leak, so that I can make a proper fix or proper
documentation of it.

Thank you for the patch too, but it can not be accepted as it would
bread some copy constructors.

--
Regards,
__ ___ ___ ____ __
/ |/ /_ __/ __/ __ \/ / Mr. Sinisa Milivojevic
/ /|_/ / // /\ \/ /_/ / /__ MySQL AB, Fulltime Developer
/_/ /_/\_, /___/\___\_\___/ Larnaca, Cyprus
<___/ www.mysql.com


------------------------------------------------------------ ---------
Before posting, please check:
http://www.mysql.com/manual.php (the manual)
http://lists.mysql.com/ (the list archive)

To request this thread, e-mail bugs-thread12987@lists.mysql.com
To unsubscribe, e-mail

Re: MySql++ memory leak

am 15.11.2002 01:00:34 von Benjamin Pflugmann

Hi.

On Thu 2002-11-14 at 14:52:11 +0200, sinisa@mysql.com wrote:
> Benjamin Pflugmann writes:
> >
> > The patch below should fix that. Not tested, because I don't use
> > MySQL++. The problem was that Result::operator= does not correctly
> > free resources when the instance to be assigned is an "null"
> > instance. You get such a "null" instance, e.g. if you request the
> > result of an UPDATE or when using the default constructor.
[...]
> Can I get a full source code of the example which demonstrates this
> suspicious memory leak, so that I can make a proper fix or proper
> documentation of it.

Hm. The header of Peter's mail says it went to bugs, internals and
plusplus, but I can only find it on plusplus@lists.mysql.com.

> Thank you for the patch too, but it can not be accepted as it would
> bread some copy constructors.

I thought I checked for this. Anyhow here is Peter's mail, which also
contains the test case:

http://lists.mysql.com/cgi-ez/ezmlm-cgi?8:mss:1658:200211:nc igfgfacmdpelcgbbng

Bye,

Benjamin.

--
benjamin-mysql@pflugmann.de

------------------------------------------------------------ ---------
Before posting, please check:
http://www.mysql.com/manual.php (the manual)
http://lists.mysql.com/ (the list archive)

To request this thread, e-mail bugs-thread12995@lists.mysql.com
To unsubscribe, e-mail

Re: MySql++ memory leak

am 15.11.2002 12:58:20 von Sinisa Milivojevic

Benjamin Pflugmann writes:
> Hi.
>
> On Thu 2002-11-14 at 14:52:11 +0200, sinisa@mysql.com wrote:
>
> > Thank you for the patch too, but it can not be accepted as it would
> > bread some copy constructors.
>
> I thought I checked for this. Anyhow here is Peter's mail, which also
> contains the test case:
>
> http://lists.mysql.com/cgi-ez/ezmlm-cgi?8:mss:1658:200211:nc igfgfacmdpelcgbbng
>
> Bye,
>
> Benjamin.
>
> --
> benjamin-mysql@pflugmann.de
>

Thanks.

--
Regards,
__ ___ ___ ____ __
/ |/ /_ __/ __/ __ \/ / Mr. Sinisa Milivojevic
/ /|_/ / // /\ \/ /_/ / /__ MySQL AB, Fulltime Developer
/_/ /_/\_, /___/\___\_\___/ Larnaca, Cyprus
<___/ www.mysql.com


------------------------------------------------------------ ---------
Before posting, please check:
http://www.mysql.com/manual.php (the manual)
http://lists.mysql.com/ (the list archive)

To request this thread, e-mail bugs-thread12998@lists.mysql.com
To unsubscribe, e-mail