Multi-threaded user app segfaults when using libpq with separate connections
От | Frank van Vugt |
---|---|
Тема | Multi-threaded user app segfaults when using libpq with separate connections |
Дата | |
Msg-id | 200308041729.13212.ftm.van.vugt@foxi.nl обсуждение исходный текст |
Ответы |
Re: Multi-threaded user app segfaults when using libpq with separate connections
(Tom Lane <tgl@sss.pgh.pa.us>)
|
Список | pgsql-interfaces |
Your name : Frank van Vugt Your email address : ftm.van.vugt@foxi.nl System Configuration --------------------- Architecture :Intel Pentium III / Amd Athlon XP+ Operating System :Linux 2.4.20 with glibc 2.3.2 (SuSE v8.2) PostgreSQL version :PostgreSQL-7.3.4 Compiler used :gcc v3.3 Please enter a FULL description of your problem: ------------------------------------------------ A small multi-threaded demo/poc-program using Qt (including its SQL-module which connects to PostgreSQL using libpq) is segfaulting while multiple connections are used. The code creates 10 new threads, each of which basically: - locks a mutex - adds/opens a new database connection - unlocks the mutex - using the newly created/opened connection - starts a transaction - sets transaction isolation level to SERIALIZABLE - performssome select-only queries - commits the transaction - closes the database connection Out of 10 consecutive runs, the code completes three times successfully and segfaults the other seven times. I have recompiled libpq with debugging and without optimization, the backtraces of the coredumps are included below. Important : if the unlocking of the mutex is moved to AFTER the database close, then the code seems to run without any problem each and every time Please describe a way to repeat the problem. Please try to provide a concise reproducible example, if at all possible: ---------------------------------------------------------------------- I'm not sure how to proceed from here. Obviously I'm using Qt for handling PostgreSQL connections as well as multi-threading, so rewriting my 'demo-code' in plain C++ using libpthread and libpq would probably take too much time. Maybe someone is willing to have a go at the Qt-code (just let me know and I'll mail the source), or maybe (hopefully) the information provided here will prove sufficient a clue to pinpoint the problem. The only thing I found in the mailinglist archives which *may* have some bearing to this problem is: http://archives.postgresql.org/pgsql-interfaces/2002-09/msg00042.php I'm not sure it's relevant, but please be advised that the PostgreSQL driver in Qt has the following code included in order to allow compilation: // PostgreSQL header <utils/elog.h> included by <postgres.h> redefines DEBUG. #if defined(DEBUG) # undef DEBUG #endif #include <postgres.h> #include <libpq/libpq-fs.h> // PostgreSQL header <catalog/pg_type.h> redefines errno erroneously. #if defined(errno) # undef errno #endif #define errno qt_psql_errno #include <catalog/pg_type.h> #undef errno Furthermore, I found that the 7.4devdocs talk about the --enable-thread-safety option for ./configure, but I don't think that applies to my platform? => backtraces of coredumps included below Best, Frank. ======================================================== The results of ten sequentially executed runs: -+-+-+- #0 0x40cc1b2b in realloc () from /lib/libc.so.6 (gdb) where #0 0x40cc1b2b in realloc () from /lib/libc.so.6 #1 0x40d8c7ac in pqReadData (conn=0x80c0fc0) at fe-misc.c:483 #2 0x40d8a335 in PQgetResult (conn=0x80c0fc0) at fe-exec.c:1337 #3 0x40d8a511 in PQexec (conn=0x80c0fc0, query=0x80cb638 "set transaction isolation level SERIALIZABLE") at fe-exec.c:1441 #4 0x4063aaa7 in QPSQLResult::reset(QString const&) (this=0x80cb418, query=@0xbf7ffa9c) at sql/drivers/psql/qsql_psql.cpp:473 #5 0x4060dd34 in QSqlQuery::exec(QString const&) (this=0xbf7ffa8c, query=@0xbf7ffa9c) at sql/qsqlquery.cpp:358 #6 0x08050401 in PrintEngine::run() (this=0x80a72e0) at printengine.cpp:85 #7 0x402b4be6 in QThreadInstance::start(void*) (_arg=0x80a7374) at kernel/qthread_unix.cpp:120 #8 0x40b1dc60 in pthread_start_thread () from /lib/libpthread.so.0 (gdb) -+-+-+- #0 0x4061390d in QSqlDatabase::transaction() (this=0x80cd2e8) at sql/qsqldatabase.cpp:760 760 if ( !d->driver->hasFeature( QSqlDriver::Transactions ) ) (gdb) where #0 0x4061390d in QSqlDatabase::transaction() (this=0x80cd2e8) at sql/qsqldatabase.cpp:760 #1 0x080503cb in PrintEngine::run() (this=0x80c0b98) at printengine.cpp:83 #2 0x402b4be6 in QThreadInstance::start(void*) (_arg=0x80c0bdc) at kernel/qthread_unix.cpp:120 #3 0x40b1dc60 in pthread_start_thread () from /lib/libpthread.so.0 (gdb) -+-+-+- Third run without problems. -+-+-+- Fourth run without problems. -+-+-+- #0 0x40caf675 in fflush () from /lib/libc.so.6 (gdb) where #0 0x40caf675 in fflush () from /lib/libc.so.6 #1 0x40d8cc16 in pqSendSome (conn=0x80c10f8) at fe-misc.c:746 #2 0x40d8cc46 in pqFlush (conn=0x80c10f8) at fe-misc.c:764 #3 0x40d896e6 in PQsendQuery (conn=0x80c10f8, query=0x80cb3d0 "set transaction isolation level SERIALIZABLE") at fe-exec.c:799 #4 0x40d8a4f3 in PQexec (conn=0x80c10f8, query=0x80cb3d0 "set transaction isolation level SERIALIZABLE") at fe-exec.c:1429 #5 0x4063aaa7 in QPSQLResult::reset(QString const&) (this=0x80cb0f8, query=@0xbf7ffa9c) at sql/drivers/psql/qsql_psql.cpp:473 #6 0x4060dd34 in QSqlQuery::exec(QString const&) (this=0xbf7ffa8c, query=@0xbf7ffa9c) at sql/qsqlquery.cpp:358 #7 0x08050401 in PrintEngine::run() (this=0x80a72d0) at printengine.cpp:85 #8 0x402b4be6 in QThreadInstance::start(void*) (_arg=0x80a7364) at kernel/qthread_unix.cpp:120 #9 0x40b1dc60 in pthread_start_thread () from /lib/libpthread.so.0 (gdb) -+-+-+- #0 0x4061391e in QSqlDatabase::transaction() (this=0x80cbcb0) at sql/qsqldatabase.cpp:760 760 if ( !d->driver->hasFeature( QSqlDriver::Transactions ) ) (gdb) where #0 0x4061391e in QSqlDatabase::transaction() (this=0x80cbcb0) at sql/qsqldatabase.cpp:760 #1 0x080503cb in PrintEngine::run() (this=0x80bd358) at printengine.cpp:83 #2 0x402b4be6 in QThreadInstance::start(void*) (_arg=0x80c0a74) at kernel/qthread_unix.cpp:120 #3 0x40b1dc60 in pthread_start_thread () from /lib/libpthread.so.0 (gdb) -+-+-+- #0 0x403352a1 in QObject::connect(QObject const*, char const*, QObject const*, char const*) (sender=0x80c0bf8, signal=0x80c0b58 "2destroyed()", receiver=0x80c7660, member=0x80c0c68 "1slotResultDestroyed()") at kernel/qobject.cpp:1737 1737 QMetaObject *smeta = sender->metaObject(); (gdb) where #0 0x403352a1 in QObject::connect(QObject const*, char const*, QObject const*, char const*) (sender=0x80c0bf8, signal=0x80c0b58 "2destroyed()", receiver=0x80c7660, member=0x80c0c68 "1slotResultDestroyed()") at kernel/qobject.cpp:1737 #1 0x4060d07d in QSqlResultShared (this=0x80c7660, result=0x80cb080) at sql/qsqlquery.cpp:57 #2 0x4060d42f in QSqlQuery (this=0xbf7ff94c, r=0x80cb080) at sql/qsqlquery.cpp:213 #3 0x4063c03b in QPSQLDriver::createQuery() const (this=0x80c0bf8) at sql/drivers/psql/qsql_psql.cpp:687 #4 0x4060d874 in QSqlQuery::init(QString const&, QSqlDatabase*) (this=0xbf7ffa8c, query=@0x40a26a88, db=0x80c0ae8) at sql/qsqlquery.cpp:272 #5 0x4060d762 in QSqlQuery (this=0xbf7ffa8c, db=0x80c0ae8) at sql/qsqlquery.cpp:259 #6 0x080503dd in PrintEngine::run() (this=0x80a72e0) at printengine.cpp:84 #7 0x402b4be6 in QThreadInstance::start(void*) (_arg=0x80a7374) at kernel/qthread_unix.cpp:120 #8 0x40b1dc60 in pthread_start_thread () from /lib/libpthread.so.0 (gdb) -+-+-+- #0 0x4061396d in QSqlDatabase::commit() (this=0x80c0ae8) at sql/qsqldatabase.cpp:775 775 if ( !d->driver->hasFeature( QSqlDriver::Transactions ) ) (gdb) where #0 0x4061396d in QSqlDatabase::commit() (this=0x80c0ae8) at sql/qsqldatabase.cpp:775 #1 0x08050b9d in PrintEngine::run() (this=0x80a72e0) at printengine.cpp:118 #2 0x402b4be6 in QThreadInstance::start(void*) (_arg=0x80a7374) at kernel/qthread_unix.cpp:120 #3 0x40b1dc60 in pthread_start_thread () from /lib/libpthread.so.0 (gdb) -+-+-+- Nineth run without problems -+-+-+- #0 0x40cc6a01 in strlen () from /lib/libc.so.6 (gdb) where #0 0x40cc6a01 in strlen () from /lib/libc.so.6 #1 0x4071bf33 in internalLatin1ToUnicode (str=0xbf7ff89c "\b\021\f\b .¡@Äø\177¿êÀn@ .¡@üø\177¿Dù\177¿9¬c@üø\177¿,ù\177¿\002", len=0x83ffbbd8, maxlen=3212834996) at tools/qstring.cpp:1164 #2 0x4071cb0b in QString (this=0xbf7ff89c, str=0x83ffbbd8 <Address 0x83ffbbd8 out of bounds>) at tools/qstring.cpp:1473 #3 0x40638d4f in qMakeError (err=@0xbf7ff92c, type=2, p=0x80ca2d0) at sql/drivers/psql/qsql_psql.cpp:118 #4 0x4063ac39 in QPSQLResult::reset(QString const&) (this=0x80ca5d8, query=@0xbf7ffa9c) at sql/drivers/psql/qsql_psql.cpp:489 #5 0x4060dd34 in QSqlQuery::exec(QString const&) (this=0xbf7ffa8c, query=@0xbf7ffa9c) at sql/qsqlquery.cpp:358 #6 0x08050401 in PrintEngine::run() (this=0x80a72e0) at printengine.cpp:85 #7 0x402b4be6 in QThreadInstance::start(void*) (_arg=0x80a7374) at kernel/qthread_unix.cpp:120 #8 0x40b1dc60 in pthread_start_thread () from /lib/libpthread.so.0 (gdb) -+-+-+-
В списке pgsql-interfaces по дате отправления:
Следующее
От: Tom LaneДата:
Сообщение: Re: Multi-threaded user app segfaults when using libpq with separate connections