Results 1 to 4 of 4

Thread: Crash in libssl when using Qt's Postgresql driver

  1. #1
    Join Date
    Mar 2009
    Posts
    3
    Thanks
    1

    Default Crash in libssl when using Qt's Postgresql driver

    Hello,

    I have just migrated from a 32bit system to a new 64bit system, running Kubuntu Natty and Qt 4.7.2. I have recompiled an application that used to work perfectly on the 32bit system and now I am getting a crash while inserting rows into a Postgresql database.

    The following is the code, it just reads a CSV file line by line and inserts each line into a Postgresql table. The database connection has been opened successfully at a different place in the application. The crash occurs at query.exec() inside the while() loop on line 51:

    Qt Code:
    1. void TickerImportThread::run()
    2. {
    3. status = true;
    4.  
    5. QSqlQuery query;
    6. QFile file(filename);
    7.  
    8. if ( !file.open(QIODevice::Text | QIODevice::ReadOnly) )
    9. {
    10. status = false;
    11. return;
    12. }
    13.  
    14. QSqlDatabase::database().transaction();
    15.  
    16. if ( !query.exec("DELETE FROM \"bardata_M1\"") )
    17. {
    18. status = false;
    19. QSqlError error = query.lastError();
    20. qDebug() << Q_FUNC_INFO << "SQL Error: " << error.databaseText() << error.driverText();
    21. QSqlDatabase::database().rollback();
    22. return;
    23. }
    24.  
    25. QByteArray line;
    26. QList<QByteArray> items;
    27. long filesize = file.size();
    28. long completed = 0;
    29. int percentage = 0;
    30.  
    31. if ( !query.prepare("INSERT INTO \"bardata_M1\" (symbol, \"time\", open, high, low, \"close\") VALUES ('EURUSD', :v_time, :v_open, :v_high, :v_low, :v_close)") )
    32. {
    33. status = false;
    34. QSqlError error = query.lastError();
    35. qDebug() << Q_FUNC_INFO << "SQL Error: " << error.databaseText() << error.driverText();
    36. QSqlDatabase::database().rollback();
    37. return;
    38. }
    39.  
    40. while ( !file.atEnd() )
    41. {
    42. line = file.readLine();
    43. items = line.split(',');
    44.  
    45. query.bindValue(":v_time", QString(items[0]) + " " + QString(items[1]));
    46. query.bindValue(":v_open", items[2]);
    47. query.bindValue(":v_high", items[3]);
    48. query.bindValue(":v_low", items[4]);
    49. query.bindValue(":v_close", items[5]);
    50.  
    51. if ( !query.exec() )
    52. {
    53. status = false;
    54. QSqlError error = query.lastError();
    55. qDebug() << Q_FUNC_INFO << "SQL Error: " << error.databaseText() << error.driverText();
    56. QSqlDatabase::database().rollback();
    57. return;
    58. }
    59.  
    60. completed += line.length();
    61. double newpercentage = (double)completed / (double)filesize * 100;
    62. if ( round(newpercentage) > percentage )
    63. {
    64. percentage = round(newpercentage);
    65. emit importProgress(percentage);
    66. }
    67. }
    68.  
    69. emit importProgress(100);
    70.  
    71. QSqlDatabase::database().commit();
    72.  
    73. file.close();
    74. }
    To copy to clipboard, switch view to plain text mode 

    This is the backtrace:

    Qt Code:
    1. *** glibc detected *** /home/till/forex-build-desktop/forex: double free or corruption (fasttop): 0x000000000094aa70 ***
    2. ======= Backtrace: =========
    3. /lib/x86_64-linux-gnu/libc.so.6(+0x78a8f)[0x7ffff5370a8f]
    4. /lib/x86_64-linux-gnu/libc.so.6(cfree+0x73)[0x7ffff53748e3]
    5. /lib/libcrypto.so.0.9.8(CRYPTO_free+0x1d)[0x7fffeb6b0efd]
    6. /lib/libssl.so.0.9.8(SSL_free+0x49)[0x7fffeba0e199]
    7. /usr/lib/libpq.so.5(+0x19e8d)[0x7fffebc45e8d]
    8. /usr/lib/libpq.so.5(+0x11bc9)[0x7fffebc3dbc9]
    9. /usr/lib/libpq.so.5(PQgetResult+0x9d)[0x7fffebc3bbcd]
    10. /usr/lib/libpq.so.5(+0xfe6b)[0x7fffebc3be6b]
    11. /usr/lib/qt4/plugins/sqldrivers/libqsqlpsql.so(+0xe327)[0x7fffebe62327]
    12. /usr/lib/libQtSql.so.4(_ZN9QSqlQuery4execEv+0xc5)[0x7ffff718cf15]
    13. /home/till/forex-build-desktop/forex[0x40fc0e]
    14. /usr/lib/libQtCore.so.4(+0x74175)[0x7ffff60bf175]
    15. /lib/x86_64-linux-gnu/libpthread.so.0(+0x6d8c)[0x7ffff5e33d8c]
    16. /lib/x86_64-linux-gnu/libc.so.6(clone+0x6d)[0x7ffff53de04d]
    To copy to clipboard, switch view to plain text mode 

    I'm not sure how to debug this, my guess is that it is libssl's fault, but I could not find anything related on the web. Is there any problem in my code? If not, any tips for debugging or even fixing this?

  2. #2
    Join Date
    Mar 2009
    Posts
    3
    Thanks
    1

    Default Re: Crash in libssl when using Qt's Postgresql driver

    I found the bug by stepping through Qt's sources. The problem is obviously related to concurrent accesses to the database from two different threads. I had one thread running that was performing queries on the database and another thread (my main application thread) that was using a timer to query the database as well. When I disabled the timer, the crash disappeared.

    This makes me wonder about the thread safety of QtSql, because the documentation does not mention that two QSqlQuery instances are not allowed to access the same QSqlDatabase instance at the same time. In my case, a work around for the crash is trivial, so I'll just disable the timer while other queries are running.

  3. #3
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Crash in libssl when using Qt's Postgresql driver

    From Threads and the SQL Module:
    A connection can only be used from within the thread that created it. Moving connections between threads or creating queries from a different thread is not supported.

    In addition, the third party libraries used by the QSqlDrivers can impose further restrictions on using the SQL Module in a multithreaded program. Consult the manual of your database client for more information
    From PostgreSQL 29.17. Behavior in Threaded Programs
    One thread restriction is that no two threads attempt to manipulate the same PGconn object at the same time. In particular, you cannot issue concurrent commands from different threads through the same connection object. (If you need to run concurrent commands, use multiple connections.)
    Since Qt will be using such a connection, it also inherits PostgreSQL limitations.

    Options include using QSqlDatabase::cloneDatabase() to create an independent database connection based on an existing (default) one or creating a named connection for each thread.

  4. The following user says thank you to ChrisW67 for this useful post:

    tigloo (6th October 2011)

  5. #4
    Join Date
    Mar 2009
    Posts
    3
    Thanks
    1

    Default Re: Crash in libssl when using Qt's Postgresql driver

    Thanks for the information, I expected to find that in the class documentation itself but did not see it there. Using QSqlDatabase::cloneDatabase() is a great tip.

Similar Threads

  1. QPSQL + QT4 (Postgresql driver bug)
    By l2succes in forum Qt Programming
    Replies: 8
    Last Post: 12th March 2011, 23:52
  2. Replies: 2
    Last Post: 11th February 2011, 17:53
  3. PostgreSQL driver support
    By treyhaslem in forum Newbie
    Replies: 14
    Last Post: 26th October 2010, 09:01
  4. PostgreSQL driver
    By clusty in forum Qt Programming
    Replies: 1
    Last Post: 21st August 2008, 00:55
  5. QT4 and Postgresql driver
    By alphaqt in forum Installation and Deployment
    Replies: 6
    Last Post: 27th February 2006, 15:50

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.