Version: 1.0.1+ #3214 (using KDE KDE 3.5.8) Installed from: SuSE RPMs Compiler: gcc (GCC) 4.2.1 OS: Linux Konversation crashes on startup upon autoconnect to IRC servers. It also crashes when not using autoconnect, but connecting manually. Only sometimes (in 10% of the cases), the crash did not happen. Analysis ~~~~~~~~ I have investigated this using GDB, however, I found odd values in the datastructures affected, suggesting a buffer overrun or similar. Valgrind memcheck has revealed following stack trace: ==11992== ==11992== Invalid read of size 4 ==11992== at 0x495BE92: KNetwork::KBufferedSocket::closeNow() (kbufferedsocket.cpp:293) ==11992== by 0x495060F: KNetwork::KBufferedSocket::slotReadActivity() (kbufferedsocket.cpp:345) ==11992== by 0x495BB28: KNetwork::KBufferedSocket::qt_invoke(int, QUObject*) (kbufferedsocket.moc:97) ==11992== by 0x4D2A8AC: QObject::activate_signal(QConnectionList*, QUObject*) (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x4D2B34F: QObject::activate_signal(int, int) (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x505F49F: QSocketNotifier::activated(int) (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x4D483EF: QSocketNotifier::event(QEvent*) (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x4CCC0AB: QApplication::internalNotify(QObject*, QEvent*) (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x4CCCE95: QApplication::notify(QObject*, QEvent*) (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x4918A61: KApplication::notify(QObject*, QEvent*) (kapplication.cpp:552) ==11992== by 0x4CC0520: QEventLoop::activateSocketNotifiers() (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x4C7B235: QEventLoop::processEvents(unsigned) (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x4CE2C2F: QEventLoop::enterLoop() (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x4CE2AC5: QEventLoop::exec() (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x4CCBC1E: QApplication::exec() (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x8126EDF: main (main.cpp:112) ==11992== Address 0x69C1F68 is 64 bytes inside a block of size 76 free'd ==11992== at 0x4022156: operator delete(void*) (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so) ==11992== by 0x495C4EF: KNetwork::KBufferedSocket::~KBufferedSocket() (kbufferedsocket.cpp:65) ==11992== by 0x811C0EA: Server::connectToIRCServer() (server.cpp:436) ==11992== by 0x811D0CD: Server::broken(int) (server.cpp:733) ==11992== by 0x811D42C: Server::closed() (server.cpp:1366) ==11992== by 0x811EF22: Server::qt_invoke(int, QUObject*) (server.moc:880) ==11992== by 0x4D2A8AC: QObject::activate_signal(QConnectionList*, QUObject*) (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x4D2B44C: QObject::activate_signal(int) (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x49494FB: KNetwork::KClientSocketBase::closed() (kclientsocketbase.moc:186) ==11992== by 0x495BC49: KNetwork::KClientSocketBase::close() (kclientsocketbase.cpp:277) ==11992== by 0x495BE91: KNetwork::KBufferedSocket::closeNow() (kbufferedsocket.cpp:292) ==11992== by 0x495060F: KNetwork::KBufferedSocket::slotReadActivity() (kbufferedsocket.cpp:345) ==11992== by 0x495BB28: KNetwork::KBufferedSocket::qt_invoke(int, QUObject*) (kbufferedsocket.moc:97) ==11992== by 0x4D2A8AC: QObject::activate_signal(QConnectionList*, QUObject*) (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x4D2B34F: QObject::activate_signal(int, int) (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x505F49F: QSocketNotifier::activated(int) (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x4D483EF: QSocketNotifier::event(QEvent*) (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x4CCC0AB: QApplication::internalNotify(QObject*, QEvent*) (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x4CCCE95: QApplication::notify(QObject*, QEvent*) (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x4918A61: KApplication::notify(QObject*, QEvent*) (kapplication.cpp:552) ==11992== by 0x4CC0520: QEventLoop::activateSocketNotifiers() (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x4C7B235: QEventLoop::processEvents(unsigned) (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x4CE2C2F: QEventLoop::enterLoop() (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x4CE2AC5: QEventLoop::exec() (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x4CCBC1E: QApplication::exec() (in /usr/lib/qt3/lib/libqt-mt.so.3.3.8) ==11992== by 0x8126EDF: main (main.cpp:112) ==11992== Thus, it is highly probable that within this code path ==11992== by 0x495BE91: KNetwork::KBufferedSocket::closeNow() (kbufferedsocket.cpp:292) the KBufferedSocket which is currently in use by currently executed methods on the stack is deleted, rendering this code path ==11992== at 0x495BE92: KNetwork::KBufferedSocket::closeNow() (kbufferedsocket.cpp:293) already as invalid. The reason is that destroying calling notification clients of KBufferedSocket and destroying the same KBufferedSocket have to be decoupled, while they are not. The reason it happened only 90% of the time instead of 100% of the time: The code path affected is only executed if the connection to first IRC server on the list is for some reason terminated (for example, for fascistic reasins with the message "[465] No hosts from Asia-pacific on this server, thanks.. ") and a second IRC server has to be contacted. Solution ~~~~~~~~ Index: konversation/src/server.cpp =================================================================== --- konversation/src/server.cpp (Revision 736061) +++ konversation/src/server.cpp (Arbeitskopie) @@ -730,7 +730,7 @@ .arg(m_serverGroup->serverByIndex(m_currentServerIndex).server()); statusView->appendServerMessage(i18n("Error"),error ); - connectToIRCServer(); + QTimer::singleShot(0, this, SLOT(connectToIRCServer())); } else { Please apply. This bug is inherent in Konversation 1.0.1 (the release version) and it is a show-stopper. Thus I'd suggest releasing Konversation 1.0.2 after applying this patch.
Thanks for the patch; I've applied it in SVN revision 736100. Calling connectToIRCServer() from the event loop does fix advancing to the next server in the list, although I'm unable to reproduce the crash you've seen in the absence of the change, rather, the connection attempt simply goes awry. In any case, the code for what broken() does is currently being slated for replacement for the next release (the current code is pretty rotten, as you can see).
*** Bug has been marked as fixed ***.