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 по дате отправления:

Предыдущее
От: markw@osdl.org
Дата:
Сообщение: Re: load database from ascii files
Следующее
От: Tom Lane
Дата:
Сообщение: Re: Multi-threaded user app segfaults when using libpq with separate connections