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

List:       kde-devel
Subject:    Problem with KCompTreeNode on Windows (or: destruction order of static objects?)
From:       Kevin Funk <krf () gmx ! de>
Date:       2013-11-30 17:50:08
Message-ID: 1449999.vPSzWaihNz () kerberos
[Download RAW message or body]

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?)

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?

Greets

[1] https://bugs.kde.org/show_bug.cgi?id=243375 (initial bug report)
[2] https://bugs.kde.org/show_bug.cgi?id=327599 (contains stack traces)

-- 
Kevin Funk

>> 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