[kontact] [Bug 370646] Crash when opening Kontact preferences
https://bugs.kde.org/show_bug.cgi?id=370646 --- Comment #7 from RJVB --- I see there's been a chronological glitch in my comments :-/ I wonder: shouldn't it be more elegant to do the actual unregistering (attributes.erase(x)) in the Attribute dtor? I'll need to check if the Attribute dtor is actually called when libnoteshared is unloaded and that apparently leads to freeing memory allocated ("new'ed") by that library. If it is, a lot of the above patches will be handled automatically. -- You are receiving this mail because: You are the assignee for the bug.
[kontact] [Bug 370646] Crash when opening Kontact preferences
https://bugs.kde.org/show_bug.cgi?id=370646 --- Comment #6 from RJVB --- #1 (anonymous namespace)::NoteSharedRegistrar::~NoteSharedRegistrar()() at .../kdepim-4.14.git/noteshared/attributes/attributeregistrar.cpp:44 #2 (anonymous namespace)::NoteSharedRegistrar::~NoteSharedRegistrar()() at .../kdepim-4.14.git/noteshared/attributes/attributeregistrar.cpp:43 #3 (anonymous namespace)::$_0::destroy()() at .../kdepim-4.14.git/noteshared/attributes/attributeregistrar.cpp:55 #4 __cxa_finalize() at ??:-1 #5 dyld::garbageCollectImages()() at ??:-1 #6 dlclose() at ??:-1 #7 dlclose() at ??:-1 #8 QLibraryPrivate::unload_sys()() at ??:-1 #9 QLibraryPrivate::unload()() at ??:-1 #10 QPluginLoader::unload()() at ??:-1 #11 KCModuleLoader::loadModule(KCModuleInfo const&, KCModuleLoader::ErrorReporting, QWidget*, QStringList const&)() at ??:-1 #12 KCModuleProxyPrivate::loadModule()() at ??:-1 #13 KCModuleProxy::realModule() const() at ??:-1 #14 KCMultiDialog::addModule(KCModuleInfo const&, KPageWidgetItem*, QStringList const&)() at ??:-1 #15 KSettings::DialogPrivate::createDialogFromServices()() at ??:-1 #16 KSettings::Dialog::showEvent(QShowEvent*)() at ??:-1 #17 QWidget::event(QEvent*)() at ??:-1 #18 QApplicationPrivate::notify_helper(QObject*, QEvent*)() at ??:-1 #19 QApplication::notify(QObject*, QEvent*)() at ??:-1 #20 QCoreApplication::notifyInternal(QObject*, QEvent*)() at ??:-1 -- You are receiving this mail because: You are the assignee for the bug.
[kontact] [Bug 370646] Crash when opening Kontact preferences
https://bugs.kde.org/show_bug.cgi?id=370646 --- Comment #5 from RJVB --- I don't understand how or why dynamically allocated memory can go stale when the shared library which allocated it is unloaded, but apparently something like that happens. When I replace libnoteshared's attributeregistrar's mechanism with one that create a global class instance when the library is loaded, I can clearly see that instance being destroyed. I'll have a look at the backtrace leading into that dtor, but meanwhile, here's a fix. It extends the AttributeFactory with a method that returns the newly created attribute instance, and (a circuitous) one that allows to unregister attributes. The resulting libraries are ABI compatible, and Kontact no longer crashes Patch for kdepimlibs4: diff --git akonadi/attributefactory.cpp akonadi/attributefactory.cpp index 47a8839..51306f0 100644 --- akonadi/attributefactory.cpp +++ akonadi/attributefactory.cpp @@ -30,6 +30,7 @@ #include "entityannotationsattribute.h" #include +#include #include @@ -79,7 +80,18 @@ class StaticAttributeFactory : public AttributeFactory public: StaticAttributeFactory() : AttributeFactory() -, initialized(false) {} +, initialized(false) +, notDeleted(0) { +skipList << QLatin1String("NoteDisplayAttribute") +<< QLatin1String("NoteAlarmAttribute") +<< QLatin1String("KJotsLockAttribute") +<< QLatin1String("showfoldernotesattribute"); +} +~StaticAttributeFactory() { +if (notDeleted > 0) { +kWarning(5250) << Q_FUNC_INFO << "attributes not deleted:" << notDeleted; +} +} void init() { if (initialized) { return; @@ -98,6 +110,8 @@ public: AttributeFactory::registerAttribute(); } bool initialized; +size_t notDeleted; +QStringList skipList; }; K_GLOBAL_STATIC(StaticAttributeFactory, s_attributeInstance) @@ -113,6 +127,9 @@ class AttributeFactory::Private { public: QHash attributes; +Private() { +attributes.clear(); +} }; AttributeFactory *AttributeFactory::self() @@ -132,18 +149,35 @@ AttributeFactory::~ AttributeFactory() delete d; } +#include void AttributeFactory::registerAttribute(Attribute *attr) { Q_ASSERT(attr); Q_ASSERT(!attr->type().contains(' ') && !attr->type().contains('\'') && !attr->type().contains('"')); QHash::Iterator it = d->attributes.find(attr->type()); if (it != d->attributes.end()) { -delete *it; +// if (!s_attributeInstance->skipList.contains(QLatin1String(attr->type( { +delete *it; +// } else { +// s_attributeInstance->notDeleted += 1; +// } d->attributes.erase(it); } d->attributes.insert(attr->type(), attr); } +void AttributeFactory::unRegisterAttribute(Attribute *attr) +{ +Q_ASSERT(attr); +Q_ASSERT(!attr->type().contains(' ') && !attr->type().contains('\'') && !attr->type().contains('"')); +kDebug(5250) << Q_FUNC_INFO << "deleting entry for type" << attr->type() << attr; +QHash::Iterator it = d->attributes.find(attr->type()); +if (it != d->attributes.end()) { +delete *it; +d->attributes.erase(it); +} +} + Attribute *AttributeFactory::createAttribute(const QByteArray &type) { Attribute *attr = self()->d->attributes.value(type); diff --git akonadi/attributefactory.h akonadi/attributefactory.h index 647b67e..be3b471 100644 --- akonadi/attributefactory.h +++ akonadi/attributefactory.h @@ -60,6 +60,16 @@ public: { AttributeFactory::self()->registerAttribute(new T); } +template inline static T *getRegisteredAttribute() +{ +T *attr = new T; +AttributeFactory::self()->registerAttribute(attr); +return attr; +} +inline static void deRegisterAttribute(Attribute *attr) +{ +AttributeFactory::self()->unRegisterAttribute(attr); +} /** * Creates an entity attribute object of the given type. @@ -76,6 +86,7 @@ protected: private: static AttributeFactory *self(); void registerAttribute(Attribute *attribute); +void unRegisterAttribute(Attribute *attribute); class Private; Private *const d; Patch for kdepim4: diff --git noteshared/attributes/attributeregistrar.cpp noteshared/attributes/attributeregistrar.cpp index cdcc949..56a61c0 100644 --- noteshared/attributes/attributeregistrar.cpp +++ noteshared/attributes/attributeregistrar.cpp @@ -22,19 +22,46 @@ #include +#include +#include + namespace { // Anonymous namespace; function is invisible outside this file. + +class NoteSharedRegistrar { +public: +NoteSharedRegistrar() +{ + kDebug(5500) << Q_FUNC_INFO << this; + displayAttr = Akonadi::AttributeFactory::getRegisteredAttribute(); + alarmAttr = Akon
[kontact] [Bug 370646] Crash when opening Kontact preferences
https://bugs.kde.org/show_bug.cgi?id=370646 --- Comment #4 from RJVB --- Why this happens is unclear to me, but the line const bool registered = dummy(); in libnoteshared's attributeregistrar.cpp is executed twice. I think that can only happen when the library is loaded twice. I may be saying something stupid here, but if the library gets unloaded without removing its registered attributes, are their addresses still valid when the library is loaded next? -- You are receiving this mail because: You are the assignee for the bug.
[kontact] [Bug 370646] Crash when opening Kontact preferences
https://bugs.kde.org/show_bug.cgi?id=370646 --- Comment #3 from RJVB --- I ran kontact through valgrind to get another angle. I think in the end it just confirms what I already thought: ``` --72548-- run: /usr/bin/dsymutil "/opt/local/lib/kde4/kcm_knote.so" --72548-- run: /usr/bin/dsymutil "/opt/local/lib/libknotesprivate.4.14.21.dylib" --72548-- run: /usr/bin/dsymutil "/opt/local/lib/libnoteshared.4.14.21.dylib" --72548-- run: /usr/bin/dsymutil "/opt/local/lib/libkdnssd.4.14.21.dylib" warning: (x86_64) /tmp/lto.o unable to open object file warning: no debug symbols in executable (-arch x86_64) ==72548== Invalid read of size 8 ==72548==at 0xCA796B9: Akonadi::AttributeFactory::registerAttribute(Akonadi::Attribute*) (attributefactory.cpp:148) ==72548==by 0x19ED63DE: global constructors keyed to a (attributefactory.h:61) ==72548==by 0x7FFF5FC11C6D: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld) ==72548==by 0x7FFF5FC11DF9: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld) ==72548==by 0x7FFF5FC0EAA1: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld) ==72548==by 0x7FFF5FC0EA2A: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld) ==72548==by 0x7FFF5FC0EA2A: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld) ==72548==by 0x7FFF5FC0E935: ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld) ==72548==by 0x7FFF5FC04B0D: dyld::runInitializers(ImageLoader*) (in /usr/lib/dyld) ==72548==by 0x7FFF5FC0B80E: dlopen (in /usr/lib/dyld) ==72548==by 0x90657ED: dlopen (in /usr/lib/system/libdyld.dylib) ==72548==by 0x38F8AFC: QLibraryPrivate::load_sys() (in /opt/local/libexec/qt4/Library/Frameworks/QtCore.framework/Versions/4/QtCore) ==72548== Address 0x1a48cd40 is not stack'd, malloc'd or (recently) free'd ==72548== *** KMail got signal 11 (Exiting) *** Dead letters dumped. KCrash: Application 'kontact' crashing... KCrash: Attempting to start /opt/local/lib/kde4/libexec/drkonqi.app/Contents/MacOS/drkonqi directly ``` -- You are receiving this mail because: You are the assignee for the bug.
[kontact] [Bug 370646] Crash when opening Kontact preferences
https://bugs.kde.org/show_bug.cgi?id=370646 --- Comment #2 from RJVB --- Backtrace below. Among the things I tried was not deleting only attributes of type NoteDisplayAttribute. That actually made things worse, somehow, causing crashes even when the application was starting up. I do wonder about the delete, which appears to be a recent addition. QHash::insert doesn't make copies as far as I read its documentation, so why the delete? To allow the code registering an attribute to forget about it? Maybe libnoteshared registers attributes it then deletes itself? Application: Kontact (kontact), signal: Segmentation fault: 11 (lldb) process attach --pid 59010 Process 59010 stopped Executable module set to "/opt/local/bin/kontact". Architecture set to: x86_64-apple-macosx. (lldb) set set term-width 200 (lldb) thread info thread #1: tid = 0x354337, 0x7fff8f109e20 libsystem_kernel.dylib`__wait4 + 8, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP (lldb) bt all * thread #1: tid = 0x354337, 0x7fff8f109e20 libsystem_kernel.dylib`__wait4 + 8, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP * frame #0: 0x7fff8f109e20 libsystem_kernel.dylib`__wait4 + 8 frame #1: 0x000107fc616e libkdeui.5.dylib`KCrash::startProcess(int, char const**, bool) + 286 frame #2: 0x000107fc5295 libkdeui.5.dylib`KCrash::defaultCrashHandler(int) + 1189 frame #3: 0x7fff8b6e15aa libsystem_platform.dylib`_sigtramp + 26 frame #4: 0x00010a5249ca libakonadi-kde.4.dylib`Akonadi::AttributeFactory::registerAttribute(this=0x7f97dbc28870, attr=0x7f97e1d8b980) + 538 at attributefactory.cpp:141 frame #5: 0x000120e3c2cf libnoteshared.4.dylib`_GLOBAL__I_a [inlined] void Akonadi::AttributeFactory::registerAttribute() + 47 at attributefactory.h:61 frame #6: 0x000120e3c2a4 libnoteshared.4.dylib`_GLOBAL__I_a [inlined] (anonymous namespace)::dummy() at attributeregistrar.cpp:30 frame #7: 0x000120e3c2a4 libnoteshared.4.dylib`_GLOBAL__I_a [inlined] __cxx_global_var_init at attributeregistrar.cpp:38 frame #8: 0x000120e3c2a4 libnoteshared.4.dylib`_GLOBAL__I_a + 4 at attributeregistrar.cpp:0 frame #9: 0x7fff61468c6e dyld`ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) + 268 frame #10: 0x7fff61468dfa dyld`ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) + 40 frame #11: 0x7fff61465aa2 dyld`ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&) + 308 frame #12: 0x7fff61465a2b dyld`ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&) + 189 frame #13: 0x7fff61465a2b dyld`ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&) + 189 frame #14: 0x7fff61465936 dyld`ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) + 54 frame #15: 0x7fff6145bb0e dyld`dyld::runInitializers(ImageLoader*) + 89 frame #16: 0x7fff6146280f dyld`dlopen + 538 frame #17: 0x7fff8eb347ee libdyld.dylib`dlopen + 59 frame #18: 0x00010981aafd QtCore`QLibraryPrivate::load_sys() + 2589 frame #19: 0x000109818000 QtCore`QLibrary::load() + 80 frame #20: 0x0001093b5281 libkdecore.5.dylib`KLibLoader::library(QString const&, QFlags) + 145 frame #21: 0x00010a0acb73 libkcmutils.4.dylib`KCModuleLoader::loadModule(KCModuleInfo const&, KCModuleLoader::ErrorReporting, QWidget*, QStringList const&) + 3635 frame #22: 0x00010a0b470c libkcmutils.4.dylib`KCModuleProxyPrivate::loadModule() + 668 frame #23: 0x00010a0b4432 libkcmutils.4.dylib`KCModuleProxy::realModule() const + 66 frame #24: 0x00010a0b0791 libkcmutils.4.dylib`KCMultiDialog::addModule(KCModuleInfo const&, KPageWidgetItem*, QStringList const&) + 385 frame #25: 0x00010a0caf6b libkcmutils.4.dylib`KSettings::DialogPrivate::createDialogFromServices() + 2715 frame #26: 0x00010a0ca053 libkcmutils.4.dylib`KSettings::Dialog::showEvent(QShowEvent*) + 1923 frame #27: 0x0001085ce1f6 QtGui`QWidget::event(QEvent*) + 1334 frame #28: 0x000108574afc QtGui`QApplicationPrivate::notify_helper(QObject*, QEvent*) + 332 frame #29: 0x000108577e99 QtGui`QApplication::notify(QObject*, QEvent*) + 8281 frame #30: 0x000109830126 QtCore`QCoreApplication::notifyInternal(QObject*, QEvent*) + 118 frame #31: 0x0001085ccf0c QtGui`QWidgetPrivate::show_helper() + 668 frame #32: 0x0001085cd9ae QtGui`QWidget::setVisible(bool) + 974 frame #33: 0x000108a314b9 QtGui`QDialog::setVisible(bool) + 169 frame #34: 0x00010732b8fc libkontactprivate.4.dylib`Kontact::MainWindow::slotPreferences() [inlined] QWidget::show(this=) + 668 at qwidget.h:497 frame #35: 0x00010732b8f1 libkontactprivate.4.dylib`Kontact
[kontact] [Bug 370646] Crash when opening Kontact preferences
https://bugs.kde.org/show_bug.cgi?id=370646 Laurent Montel changed: What|Removed |Added CC||mon...@kde.org --- Comment #1 from Laurent Montel --- Could you provide a backtrace ?:) I will not create a patch in 4.14 but if we can reproduce bug and fix it I can provide your patch for it. -- You are receiving this mail because: You are the assignee for the bug.