TelepathyNepomukService crash
David Edmundson
david at davidedmundson.co.uk
Wed Jul 27 22:28:12 CEST 2011
This is pretty much an email for George G, but it's probably
interesting to anyone else, particularly anyone who's really clever
and can actually fix this.
I spent this morning (+ a bit of this evening) trying to fix all the
crashes/issues I had with telepathy-nepomuk-service.
I've put 2 minor fixes on RB (or at least I will, when I get
post-review working)
There's one more bug that I know exactly what's going wrong, but
there's no simple fix for it.
I'll explain in detail, that way it will at least save you some debugging time.
The Crash:
#1 0x00007fffe80140b8 in Contact::init (this=0x89bca0) at
/home/david/telepathy/telepathy-nepomuk-service/contact.cpp:
#2 0x00007fffe8010ca6 in Account::onNewContact (this=0x954ee0,
contact=<value optimised out>) at
/home/david/telepathy/telepathy-nepomuk-service/account.cpp:198
#3 0x00007fffe8010ef3 in Account::onContactManagerStateChanged
(this=0x954ee0, state=<value optimised out>) at
/home/david/telepathy/telepathy-nepomuk-service/account.cpp:122
#4 0x00007fffe80111b2 in Account::onConnectionChanged (this=0x954ee0,
connection=<value optimised out>) at
/home/david/telepathy/telepathy-nepomuk-service/account.cpp:103
#5 0x00007fffe8011504 in Account::init (this=0x954ee0) at
/home/david/telepathy/telepathy-nepomuk-service/account.cpp:70
#6 0x00007fffe800e152 in Controller::onNewAccount (this=<value
optimised out>, account=<value optimised out>) at
/home/david/telepathy/telepathy-nepomuk-service/controller.cpp:149
#7 0x00007fffe800ecfa in Controller::onAccountManagerReady
(this=0x7ac620, op=<value optimised out>) at
/home/david/telepathy/telepathy-nepomuk-service/controller.cpp:106
#8 0x00007fffe800edec in Controller::qt_metacall (this=0x7ac620,
_c=QMetaObject::InvokeMetaMethod, _id=<value optimised out>,
_a=0x7fffffffcb40)
Steps to reproduce:
Connect an account, whilst it is passing the contact list. disconnect
the account.
The issue:
It creates a Contact in onNewContact, halfway through c->init() the
Contact object (our one, not the nepomuk one) deletes itself.
Reading the code, there's nothing immediately wrong, it's not threaded
so even if the account gets disconnected telepathy will only find out
once our code hits the event loop, reads that it has a new dbus
message, act appropriately and with the way our signals are set up
delete contact like it should do.
but Contact::init ends up running NepomukStorage::createContact, which
shouldn't be a problem except that it calls
"QueryServiceClient::syncQuery". This starts a new event loop.
Because there's a new event loop, all of our pending incoming dbus
calls get read, it finds out the account is disconnected, and does any
processing which destroys the Contact item even though we're still
using it. As soon as the new event loop finishes, we return to where
we were in the stack, running code in the middle of a deleted item.
Even the fact that we call deleteLater() on the contact doesn't help -
because we're running with a brand new event loop which will delete
it.
There's plenty of ways to fix this particular issue, but I feel it's
something that's probably going to come up again and again. Not just
here, but in the client code, and for that matter anyone using nepomuk
ever.
Effectively it's a little bit like as the QDialog::exec() conundrum,
http://blogs.kde.org/node/3919 which Dario linked me to once. Except
much harder to spot (as it's not called exec() anywhere), and harder
to work around, we can't QWeakPointer /every/ single object at any
point in the stack which might possible ever call syncQuery.
Maybe we need to use the async nepomuk query, or magically make the
nepomuk event loop stop being mental.
Dave
More information about the KDE-Telepathy
mailing list