[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-devel
Subject: Re: Problem with KCompTreeNode on Windows (or: destruction order of static objects?)
From: Frank Reininghaus <frank78ac () googlemail ! com>
Date: 2013-12-04 15:01:03
Message-ID: CAFoZWWiYmx3wP=hnDM3oBu9D8ZC8YWXNdn9d3N+pJuB-rgFo8A () mail ! gmail ! com
[Download RAW message or body]
Hi,
2013/11/30 Kevin Funk:
> Hey guys,
>
> My recent attempts to make KDevelop shine on Windows revealed some odd
> behaviour inside kdelibs.
>
> I need some help in order to find the right approach to fix an at least 3 year
> old bug [1] ultimately caused by the use of a static member object in the
> KCompTreeNode class (kcompletion.h) in kdelibs. Please see the attached bug
> report [2].
>
> Note that the error *only shows up on Windows*, on Linux we don't have this
> problem. I'll try to explain what's wrong in this mail.
>
> The actual issue:
> - KDevelop running:
> - We have an instance of KateGlobal owned by KateFactory,
> a plugin loaded by KDevelop
> - Some descendant of KateGlobal (KateCmd) owns a KCompTreeNode instance
> - KCompTreeNode uses a custom allocator for creating/deleting instances
> of itself, holds a static member of type KZoneAllocactor for that
> - KZoneAllocator holds the memory for all the instantiated KCompTreeNodes
>
> So we have the following object ownership (some levels omitted):
> - KateFactory
> KateGlobal
> KCompTreeNode
> KZoneAllocator (static)
>
> When closing KDevelop *under Linux*:
> - ~KateFactory, via QObjectCleanupHandler during __run_exit_handlers (glibc)
> ~KateGlobal, via call to KateGlobal::decRef()
> ~KCompTreeNode
> - ~KZoneAllocator, during __cxa__finalize (glibc)
>
> The order is fine in this case. No segfaults.
>
> However, on Windows the destruction order is different (and I cannot really
> explain why). When closing KDevelop *under Windows*:
> - ~KZoneAllocator is called first, via
> "kdeui.dll!`dynamic atexit destructor for 'KCompTreeNode::alloc''()"
> - ~KateFactory, via QObjectCleanupHandler
> ~KateGlobal
> Call to KCompTreeNode::removeItem()
>
> => Crash because memory for the KCompTreeNode instances was already freed
> by ~KZoneAllocator
>
>
> I wonder how to fix that:
> The easiest solution obviously: Get rid off the custom allocator in
> KCompTreeNode. Having a class owning its custom allocator is just plain wrong,
> right? But removing that probably has performance impacts. (Does anyone have
> benchmarks here?)
well, having a custom allocator may have some benefits. I guess that
KCompletion uses one to ensure that all KCompTreeNodes are close to
each other in memory and thus to reduce cache misses? I don't know how
much dropping the custom allocator would affect the performance, one
would have to do some benchmarking with typical KCompletion use cases.
> Just using K_GLOBAL_STATIC for the KZoneAllocator instance doesn't help
> either. I get the same destruction order + crash with that on Windows.
>
> Dynamic allocation inside KCompTreeNode doesn't work either, because
> KZoneAllocator needs to be there *before* the first KCompTreeNode is created
> and needs to there *until* the last one has been destroyed.
>
> Any ideas?
Well, here is one idea (untested): use a
QSharedPointer<KZoneAllocator> to ensure that the KZoneAllocator is
not destroyed before the last KCompletion instance using it.
Replace
static KZoneAllocator alloc;
in KCompTreeNode by
static QSharedPointer<KZoneAllocator> alloc;
and, in kcompletion.cpp,
KZoneAllocator KCompTreeNode::alloc(8192);
by
QSharedPointer<KZoneAllocator> KCompTreeNode::alloc;
In KCompTreeNode's operator new/delete, replace "alloc." by "alloc->".
Furthermore, add a QSharedPointer<KZoneAllocator> member to
KCompletionPrivate. In KCompletionPrivate's constructor, first check
if KCompTreeNode::alloc isNull(), initialize it if that is not the
case, and then copy "alloc" to the new member.
I think that this might work, and it might also improve application
start-up time because the KZoneAllocator would only be initialized on
first use of a KCompletion object.
Cheers,
Frank
>> 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