Bug 152248 - konversation crashes on startup upon autoconnect to IRC servers
Summary: konversation crashes on startup upon autoconnect to IRC servers
Status: RESOLVED FIXED
Alias: None
Product: konversation
Classification: Applications
Component: general (show other bugs)
Version: unspecified
Platform: openSUSE Linux
: NOR crash
Target Milestone: ---
Assignee: Konversation Developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-11-13 13:57 UTC by Xuân Baldauf
Modified: 2007-11-13 15:27 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Xuân Baldauf 2007-11-13 13:57:53 UTC
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.
Comment 1 Eike Hein 2007-11-13 15:23:11 UTC
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). 
Comment 2 Eike Hein 2007-11-13 15:27:12 UTC
*** Bug has been marked as fixed ***.