[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    Re: BUG: KStaticDeleters cleaned up too soon
From:       David Faure <faure () kde ! org>
Date:       2004-09-15 16:22:59
Message-ID: 200409151822.59785.faure () kde ! org
[Download RAW message or body]

On Wednesday 15 September 2004 07:00, richedw@vodafone.es wrote:
> I originally reported this as BUG 89333 =>KStaticDeleter crashes Kate on quit.
> This bug is crashing applications all over and it is being fixed at the wrong 
> places.
> I have traced it to the ~KApplication destructor when quitting .
> KGlobal::deleteStaticDeleters() deletes the all the Static Deleters and next
> KLibLoader::cleanUp() cleans up left-overs objects, which may in their 
> destructor
> try to access a static deleter that is no longer there.

This is not exactly correct.
A static deleter is a file-static object, so it's automatically created by the library
when loaded and destroyed when the library is unloaded.
KGlobal::deleteStaticDeleters() asks the static deleters to delete the object
they point to, but it doesn't delete the actual KStaticDeleter object itself
(it can't do that! It's not even on the heap).

> For instance in KateDocument destructor:
>  KateFactory::Self()->unregisterDocuments()
> this tries to access the factory held in a static deleter that's already gone 
> and crashes.
> see BUG 89333 for full explanation.

(I'm writing this offline, so I can't read bug 89333, but the above line looks
like a dreaded "intelligent destructor", i.e. a destructor that calls a method
in another class, and that's always a dangerous thing to do.
Whichever code is deleting a document in the other case than on program
exit, should do the unregister by itself, so that the deletion-on-exit simply
deletes the object and nothing else.

> In KONQUEROR same thing happens...
> 
> KFileMetaInfoProvider * KFileMetaInfoProvider::self()
> {
>     if ( !s_self )
>         s_self = sd.setObject( s_self, new KFileMetaInfoProvider() );
> 
>     return s_self;
> }
> 
> KFileMetaInfoProvider::~KFileMetaInfoProvider()
> {
>     sd.setObject( 0 );     // sd has been deleted!!!
No it's not deleted. The KFileMetaInfoProvider object is [being] deleted, but not "sd" itself.

> you'll see similar backtraces all over the place.
Actually, I don't :)

> [New Thread 16384 (LWP 2593)]
> [KCrash handler]
> #4  0x2f656c61 in ?? ()
> #5  0x4049e17e in QDict<KFilePlugin>::deleteItem(void*) ()
>    from /usr/local/kde/lib/libkio.so.4
> #6  0x41220b4a in QGDict::clear() (this=0x83f6198) at tools/qgdict.cpp:783
> #7  0x4049cc4c in QDict<KFilePlugin>::clear() ()
>    from /usr/local/kde/lib/libkio.so.4
> #8  0x4049bbc8 in QDict<KFilePlugin>::~QDict() ()
>    from /usr/local/kde/lib/libkio.so.4
> #9  0x404971a6 in KFileMetaInfoProvider::~KFileMetaInfoProvider() ()
>    from /usr/local/kde/lib/libkio.so.4
> #10 0x4049e963 in KStaticDeleter<KFileMetaInfoProvider>::destructObject() ()
>    from /usr/local/kde/lib/libkio.so.4
> #11 0x40a3b69a in KGlobal::deleteStaticDeleters() () at kglobal.cpp:189

As you can see this is from deleteStaticDeleters, so KLibLoader::cleanUp isn't called
yet, so this is unrelated to KLibLoader::cleanUp.
Off hand I don't know why the above KFilePlugin is a problem, but if you call cleanUp
before then things will get worse: the KFilePlugin will for sure be deleted already,
if you unload the library first. Unloading the library must be done last, that's for sure.

-- 
David Faure, faure@kde.org, sponsored by Trolltech to work on KDE,
Konqueror (http://www.konqueror.org), and KOffice (http://www.koffice.org).
 
>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic