Bug 291201

Summary: ktp-contactlist crashes when setting status to "Offline"
Product: [Unmaintained] telepathy Reporter: Elias Probst <mail>
Component: contactlistAssignee: Telepathy Bugs <kde-telepathy-bugs>
Status: RESOLVED FIXED    
Severity: crash CC: kde, lacsilva, mklapetek
Priority: NOR    
Version: git-latest   
Target Milestone: 0.4.0   
Platform: unspecified   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Bug Depends on:    
Bug Blocks: 285413    

Description Elias Probst 2012-01-10 19:29:21 UTC
Application: ktp-contactlist (0.2.60)
KDE Platform Version: 4.7.97 (4.8 RC2 (4.7.97) (Compiled from sources)
Qt Version: 4.7.4
Operating System: Linux 3.1.6-gentoo x86_64
Distribution: "Gentoo Base System release 2.0.3"

-- Information about the crash:
- What I was doing when the application crashed:
→ Open Contact List
→ Set status of already existing accounts to "Online"
→ Open Accounts KCM
→ Add Account
→ Jabber/XMPP
→ Jabber ID: eliasp@amessage.de / Password: something random...
→ Notification appears: "There was a problem while trying to connect eliasp@amessage.de - The SSL/TLS certificate received from server is expired"
→ Set status in Contact List to "Offline"
→ ktp-contactlist crashes

The crash can be reproduced every time.

-- Backtrace:
Application: KDE Telepathy Contact List (ktp-contactlist), signal: Segmentation fault
[KCrash Handler]
#6  size (this=0x1ea00000041) at ../../include/QtCore/../../src/corelib/tools/qvector.h:124
#7  QSortFilterProxyModelPrivate::proxy_to_source (this=0x8279b0, proxy_index=...) at itemviews/qsortfilterproxymodel.cpp:369
#8  0x00007f8c2b092fc7 in QSortFilterProxyModel::mapToSource (this=<optimized out>, proxyIndex=<optimized out>) at itemviews/qsortfilterproxymodel.cpp:2500
#9  0x00007f8c2b091cb1 in QSortFilterProxyModel::data (this=<optimized out>, index=..., role=32) at itemviews/qsortfilterproxymodel.cpp:1713
#10 0x000000000043c5ac in data (arole=32, this=0x8ecab8) at /usr/include/qt4/QtCore/qabstractitemmodel.h:398
#11 ToolTipManager::showToolTip (this=0x917e90, menuItem=...) at /var/tmp/portage/net-im/telepathy-contact-list-9999/work/telepathy-kde-contact-list-9999/tooltips/tooltipmanager.cpp:153
#12 0x000000000043c888 in ToolTipManager::qt_metacall (this=0x917e90, _c=QMetaObject::InvokeMetaMethod, _id=<optimized out>, _a=0x7fffbf5899f0) at /var/tmp/portage/net-im/telepathy-contact-list-9999/work/telepathy-contact-list-9999_build/tooltipmanager.moc:77
#13 0x00007f8c2be8c3e0 in QMetaObject::activate (sender=0x917fd0, m=<optimized out>, local_signal_index=<optimized out>, argv=0x0) at kernel/qobject.cpp:3278
#14 0x00007f8c2be8bc17 in QObject::event (this=0x917fd0, e=<optimized out>) at kernel/qobject.cpp:1181
#15 0x00007f8c2ab801f8 in QApplicationPrivate::notify_helper (this=0x6936b0, receiver=0x917fd0, e=0x7fffbf58a130) at kernel/qapplication.cpp:4481
#16 0x00007f8c2ab848b0 in QApplication::notify (this=<optimized out>, receiver=0x917fd0, e=0x7fffbf58a130) at kernel/qapplication.cpp:4360
#17 0x00007f8c2caf0600 in KApplication::notify (this=0x7fffbf58a470, receiver=0x917fd0, event=0x7fffbf58a130) at /var/tmp/portage/kde-base/kdelibs-4.7.97-r1/work/kdelibs-4.7.97/kdeui/kernel/kapplication.cpp:311
#18 0x00007f8c2be79ce0 in QCoreApplication::notifyInternal (this=0x7fffbf58a470, receiver=0x917fd0, event=0x7fffbf58a130) at kernel/qcoreapplication.cpp:787
#19 0x00007f8c2bea3269 in sendEvent (event=0x7fffbf58a130, receiver=<optimized out>) at kernel/qcoreapplication.h:215
#20 QTimerInfoList::activateTimers (this=0x68bda0) at kernel/qeventdispatcher_unix.cpp:603
#21 0x00007f8c2bea0566 in timerSourceDispatch (source=<optimized out>) at kernel/qeventdispatcher_glib.cpp:184
#22 idleTimerSourceDispatch (source=<optimized out>) at kernel/qeventdispatcher_glib.cpp:231
#23 0x00007f8c26d6e0a2 in g_main_dispatch (context=0x68ace0) at gmain.c:2441
#24 g_main_context_dispatch (context=0x68ace0) at gmain.c:3011
#25 0x00007f8c26d6e7e8 in g_main_context_iterate (context=0x68ace0, block=1, dispatch=1, self=<optimized out>) at gmain.c:3089
#26 0x00007f8c26d6e9a4 in g_main_context_iteration (context=0x68ace0, may_block=1) at gmain.c:3152
#27 0x00007f8c2bea0b3c in QEventDispatcherGlib::processEvents (this=0x659dc0, flags=<optimized out>) at kernel/qeventdispatcher_glib.cpp:422
#28 0x00007f8c2ac174c6 in QGuiEventDispatcherGlib::processEvents (this=<optimized out>, flags=<optimized out>) at kernel/qguieventdispatcher_glib.cpp:204
#29 0x00007f8c2be79268 in QEventLoop::processEvents (this=<optimized out>, flags=...) at kernel/qeventloop.cpp:149
#30 0x00007f8c2be7945f in QEventLoop::exec (this=0x7fffbf58a3c0, flags=...) at kernel/qeventloop.cpp:201
#31 0x00007f8c2be7cb59 in QCoreApplication::exec () at kernel/qcoreapplication.cpp:1064
#32 0x000000000042e65d in main (argc=1, argv=0x7fffbf58a748) at /var/tmp/portage/net-im/telepathy-contact-list-9999/work/telepathy-kde-contact-list-9999/main.cpp:62

Possible duplicates by query: bug 259161.

Reported using DrKonqi
Comment 1 Martin Klapetek 2012-01-11 10:30:48 UTC
This one is a bit tricky, it's a race condition. Basically what happens is that when you click "Offline" and the combobox closes, your mouse stays right above some contact and a tooltip is spawned. But before it can be fully drawn etc., the backend model data are already gone and therefore it hits null pointer and crashes.

I have basic safety checks in place, but it will have to be more sophisticated as that does not prevent the crash.

We could perhaps listen to some signal "going offline" (from global presence) and don't create tooltips when it receive that signal.
Comment 2 Martin Klapetek 2012-01-15 22:54:37 UTC
*** Bug 291399 has been marked as a duplicate of this bug. ***
Comment 3 Martin Klapetek 2012-01-15 22:56:18 UTC
We need to solve this before 0.3 release as it is very annoying and very easy
to trigger.
Comment 4 David Edmundson 2012-01-15 23:59:28 UTC
But this crash is inside Qt itself, which implies 
 - either it's a Qt bug
 - our models are in a corrupt state for a small period of time.
 
QSortFilterProxyModelPrivate::proxy_to_source checks the index is valid. 

It must thinks it is.. otherwise it wouldn't continue and get to the line that crashes presumably "m_sourceRows->size()" in QSortFilterProxyModelPrivate::proxy_to_source

Our models should never be in a corrupt state, especially as all our stuff runs in one thread.

I made a version once that linked against Qt model test lib, we might want to try linking against that again and then triggering this issue. It might tell us where it's screwed. Failing that someone should re-read through accounts-model and look for potential discrepancies where an index could look valid even when it's not.
Comment 5 David Edmundson 2012-01-16 00:02:35 UTC
Eliasp (and other people who have seen this crash) were you in groups view or accounts view?
Comment 6 Elias Probst 2012-01-16 05:56:58 UTC
(In reply to comment #5)
> Eliasp (and other people who have seen this crash) were you in groups view or
> accounts view?

You mean whether I was using the compact or the full list view? I'm using 'compact'.
Comment 7 Luis Silva 2012-01-16 08:38:10 UTC
It used to happen in account view. Curiously enough, after the latest qt upgrade (yesterday) I don't seem to be able to trigger this crash anymore. I am using Kubuntu packages for qt but compiling telepathy-qt from source (master).
Comment 8 Martin Klapetek 2012-01-16 10:34:51 UTC
Few notes:
 - I tested it only with groups
 - Listening to the model's rowsRemoved() shows that the model emits the signal way before the data is actually removed (which might actually be correct), but there's a notable delay, therefore the model might still have "valid" indexes (but that's just a wild guess after severe sleep deprivation and sounds really wrong as the indexes imho should be invalidated by the remove-rows call)
 - I tested with recent Qt git snapshot, 100% reproducible
 - Checking for indexes in the tooltip part does not help, it returns true for isValid() everytime

Checking for the indexes
Comment 9 David Edmundson 2012-01-16 10:42:34 UTC
That wouldn't cause a crash though, you'd get it if you emitted rowsRemoved and there was a delay before removing from parent->mPriv->children.. and there isn't.
Comment 10 David Edmundson 2012-01-19 01:30:48 UTC
Right. We both made this supercomplicated when it turned out to be really really easy when we look in the right place.

QModelIndex.isValid() simply checks model exists and that rows + columns are non negative, it's not a continual check that works forever. It possibly checks < rowCount on creation, but it's not checked each time you called isValid();

We had code in the tooltip-manager that:
1) saved a qmodelindex
2) waited a bit
3) used that modelindex

You should /never ever ever/ store a QModelIndex.

Patch
-    QModelIndex        item;
+    QPersistentModelIndex        item;

isValid now updates correctly so we don't crash.
Seems to fix it. If you test it, tomorrow I'll ship it if you're happy enough.

Alternate fix is to re-request the model index in prepareToolTip.
Comment 11 Martin Klapetek 2012-01-19 08:47:17 UTC
While testing this I'm reliably unable to reproduce it anymore (I was able to do that 100%).

'Ship it' from me!
Comment 12 David Edmundson 2012-01-19 12:40:25 UTC
Git commit b007f34980c2767d2a22e961ef6bb5dda237498f by David Edmundson.
Committed on 19/01/2012 at 13:39.
Pushed by davidedmundson into branch 'master'.

Tooltip manager should store QPersistentModelIndexes not QModelIndexes

fixes a crash

M  +1    -1    tooltips/tooltipmanager.cpp

http://commits.kde.org/telepathy-contact-list/b007f34980c2767d2a22e961ef6bb5dda237498f