1 message in com.mysql.lists.plusplusMySQL++ Memory leak| From | Sent On | Attachments |
|---|---|---|
| Peter A. Kerzum | 13 Nov 2002 06:31 | .cc |
| Subject: | MySQL++ Memory leak![]() |
|---|---|
| From: | Peter A. Kerzum (ker...@mail.ru) |
| Date: | 11/13/2002 06:31:14 AM |
| List: | com.mysql.lists.plusplus |
| Attachments: | ![]() leak.cc - 2k |
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%40FreeBSD.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.2b4ef27a%40posting.google.com&rnum=2
// -------------------- Proof of concept --------------------------- #include <iostream> #include <mysql++> 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);
// This is another workaround:
// res.purge() // I soppose this is not called or called incorrectly in
ResUse::operator=
// 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 << '.'; } }
// Table creation command: // CREATE TABLE a ( i integer);
--
Sincerely yours Peter Kerzum





.cc