Hi all,
I think Ive found what may be a Mysql++ bug related to the ResUse
destructor. Although my own code where Ive encountered the problem is
large and complicated, Ive boiled it down to a simple testcase as
illustrated below. See comments in code.
//// start
#include <mysql++/mysql++.h>
#include <iostream>
// adjust as needed for your server
#define DB_DB "test"
#define DB_HOST "myhost"
#define DB_USER "myuser"
#define DB_PASS "mypass"
using namespace std;
using namespace mysqlpp;
int main(int argc,char **argv) {
// in my code I need to have control over if and when a connection is made
// and then want to pass around a pointer to the connection to things that
// need it. So I create a connection as follows instead of doing
// mysqlpp::Connection con(false); as in the examples
Connection *con=new Connection(false);
// connect is a separate operation since there's no way to
// disable exceptions with the connect on create method
con->connect(DB_DB,DB_HOST,DB_USER,DB_PASS);
// create a query and get results
Query q=con->query();
ResUse use=q.use("show variables like 'version'");
// show results
while(Row row=use.fetch_row()) {
cout << row.at(0) << "=" << row.at(1) << endl;
}
// close connection
con->close();
// done with it, delete it
delete con;
// now I wouldnt expect to do anything
// anymore with row or use now that connection
// has been closed and deleted, however,
// 'use' goes out of scope here
// and it's destructor is invisibly called
// problem is, it references an internal pointer
// to con, which no longer is valid (result.cpp, 69)
// a crash may result.
}
//// end
Code may or may not crash depending on how things may be arranged, your
compiler, and platform (GCC4 on linux x86 in my case). I first found the
bug with valgrind (www.valgrind.org)
It can be worked around by not using a pointer, but it would be inconvenient
in my code and nothing in the documentation says I can't or shouldn't do it
this way.
Even then, if I don't use pointers I'm not sure it isn't still a problem as
there's nothing that guarantees in what order C++ calls destructors when
stack allocated variables go out of scope and Connection could be deleted
before ResUse.
Thanks.
-----
David Wojtowicz, Sr. Research Programmer, Sysadmin
Dept of Atmospheric Sciences / Computer Services
University of Illinois at Urbana-Champaign
davidw@stripped (217) 333-8390