Details
-
Bug
-
Resolution: Incomplete
-
P2: Important
-
None
-
5.12.0
-
None
-
Linux
Description
There seems to be something wrong in the way connect -> disconnect -> connect is handled. I don't know if this is a problem in QMYSQL or not.
Important detail: I've only managed to reproduce this issue when connecting to remote databases.
Output from ASAN when it crashes:
AddressSanitizer:DEADLYSIGNAL ================================================================= ==5792==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000030 (pc 0x7f0cf9087960 bp 0x7f0cda9459d0 sp 0x7f0cda945998 T13) ==5792==The signal is caused by a READ memory access. ==5792==Hint: address points to the zero page. #0 0x7f0cf908795f (/lib/x86_64-linux-gnu/libpthread.so.0+0xa95f) #1 0x7f0ceb45682f (/usr/lib/x86_64-linux-gnu/libmysqlclient.so.20+0x8382f) #2 0x7f0ceb46085f (/usr/lib/x86_64-linux-gnu/libmysqlclient.so.20+0x8d85f) #3 0x7f0ceb44653d (/usr/lib/x86_64-linux-gnu/libmysqlclient.so.20+0x7353d) #4 0x7f0ceb4309c7 (/usr/lib/x86_64-linux-gnu/libmysqlclient.so.20+0x5d9c7) #5 0x7f0ceb408841 in mysql_real_connect (/usr/lib/x86_64-linux-gnu/libmysqlclient.so.20+0x35841) #6 0x7f0ceb7e7d52 in QMYSQLDriver::open(QString const&, QString const&, QString const&, QString const&, int, QString const&) (/home/thomas/Qt/5.12.0/gcc_64/plugins/sqldrivers/libqsqlmysql.so+0x9d52) #7 0x7f0cf9c989cd in QSqlDatabase::open(QString const&, QString const&) (/home/thomas/Qt/5.12.0/gcc_64/lib/libQt5Sql.so.5+0x199cd)
In order to troubleshoot, and to demonstrate the problem, I've created a docker based sample located here https://github.com/tskardal/mysigsegv. This should be straightforward to use if you have Docker and docker-compose installed. If not, I've also written a more detailed explanation on how to do it manually in the README.md file available at GitHub.
For convenience, here's a the dummy application code:
#include <QCoreApplication> #include <QDebug> #include <QtSql> void connect(const QString &connectionName) { auto host = "192.168.137.42"; auto user = "testusr"; auto pwd = "testusr"; auto dbName = "testdb"; QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", connectionName); db.setHostName(host); db.setPort(3306); db.setUserName(user); db.setPassword(pwd); db.setDatabaseName(dbName); bool open = db.open(); // 2nd time causes segfault if (!open) { qDebug() << "Failed to open connection"; return; } QSqlQuery q("SHOW VARIABLES LIKE '%version%';", db); while (q.next()) { qDebug() << q.value(0).toString() << " = " << q.value(1).toString(); } } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); connect("test"); QSqlDatabase::removeDatabase("test"); connect("test"); QSqlDatabase::removeDatabase("test"); qDebug() << "Done"; return a.exec(); }