Bug 327599

Summary: Crash when closing KDevelop (Windows)
Product: [Applications] kate Reporter: Kevin Funk <kfunk>
Component: generalAssignee: KWrite Developers <kwrite-bugs-null>
Status: RESOLVED FIXED    
Severity: crash CC: christoph, kfunk
Priority: NOR Keywords: drkonqi
Version: Git   
Target Milestone: ---   
Platform: Compiled Sources   
OS: Microsoft Windows   
Latest Commit: Version Fixed In: 5.0
Sentry Crash Report:

Description Kevin Funk 2013-11-14 09:52:26 UTC
Application: kdevelop (4.6.60)
KDE Platform Version: 4.11.3 (Compiled from sources)
Qt Version: 4.8.5
Operating System: WindowsNT Windows 7 i686
Distribution (Platform): MS Windows

-- Information about the crash:
- What I was doing when the application crashed:

Closed KDevelop.

This is a windows build using MSVC 2010. Kate compiled from sources using Git master.

-- Backtrace:
Application: KDevelop (kdevelop), signal: EXCEPTION_ACCESS_VIOLATION


kdecore.dll!KZoneAllocator::deallocate() [d:\kderoot\git\kdelibs\kdecore\util\kallocator.cpp @ 245] at 0x68ad28c7
kdeui.dll!KCompTreeNode::remove() [d:\kderoot\git\kdelibs\kdeui\util\kcompletion.cpp @ 800] at 0x682db07f
kdeui.dll!KCompletion::removeItem() [d:\kderoot\git\kdelibs\kdeui\util\kcompletion.cpp @ 211] at 0x682db301
katepartinterfaces.dll!KateCmd::unregisterCommand() [d:\kderoot\git\kate\part\utils\katecmd.cpp @ 71] at 0x635bb745
katepartinterfaces.dll!KateScriptManager::~KateScriptManager() [d:\kderoot\git\kate\part\script\katescriptmanager.cpp @ 55] at 0x63481c10
katepartinterfaces.dll!KateScriptManager::`scalar deleting destructor'() [[unknown] @ -1] at 0x63481f58
katepartinterfaces.dll!KateGlobal::~KateGlobal() [d:\kderoot\git\kate\part\utils\kateglobal.cpp @ 225] at 0x635b4756
katepartinterfaces.dll!KateGlobal::`vector deleting destructor'() [[unknown] @ -1] at 0x635b4ded
katepartinterfaces.dll!KateGlobal::decRef() [d:\kderoot\git\kate\part\utils\kateglobal.h @ 222] at 0x634206c6
katepart.dll!KateFactory::`scalar deleting destructor'() [[unknown] @ -1] at 0x641b14dc
QtCore4.dll!QObjectCleanupHandler::clear() [d:\kderoot\git\qt-4.8.2\src\corelib\kernel\qobjectcleanuphandler.cpp @ 139] at 0x68746097
QtCore4.dll!QObjectCleanupHandler::~QObjectCleanupHandler() [d:\kderoot\git\qt-4.8.2\src\corelib\kernel\qobjectcleanuphandler.cpp @ 87] at 0x68745e9b
kdecore.dll!QObjectCleanupHandler::`scalar deleting destructor'() [[unknown] @ -1] at 0x68add029
kdecore.dll!_k_factorycleanup__LINE__::destroy() [d:\kderoot\git\kdelibs\kdecore\util\kpluginfactory.cpp @ 29] at 0x68adc7e4
kdecore.dll!_CRT_INIT() [f:\dd\vctools\crt_bld\self_x86\crt\src\crtdll.c @ 415] at 0x68afd440
kdecore.dll!__DllMainCRTStartup() [f:\dd\vctools\crt_bld\self_x86\crt\src\crtdll.c @ 526] at 0x68afd55c
kdecore.dll!_DllMainCRTStartup() [f:\dd\vctools\crt_bld\self_x86\crt\src\crtdll.c @ 476] at 0x68afd5d9
ntdll.dll!RtlQueryEnvironmentVariable() [[unknown] @ -1] at 0x771d99a0
ntdll.dll!LdrShutdownProcess() [[unknown] @ -1] at 0x771ed6ba
ntdll.dll!RtlExitUserProcess() [[unknown] @ -1] at 0x771ed55c
kernel32.dll!ExitProcess() [[unknown] @ -1] at 0x76787363
MSVCR100.dll!_query_new_mode() [[unknown] @ -1] at 0x72317997
MSVCR100.dll!_query_new_mode() [[unknown] @ -1] at 0x72317ab0
MSVCR100.dll!exit() [[unknown] @ -1] at 0x72317b1d
kdevelop.exe!__tmainCRTStartup() [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 518] at 0xca345e
kernel32.dll!BaseThreadInitThunk() [[unknown] @ -1] at 0x76783677
ntdll.dll!RtlInitializeExceptionChain() [[unknown] @ -1] at 0x771d9f42
ntdll.dll!RtlInitializeExceptionChain() [[unknown] @ -1] at 0x771d9f15

Reported using DrKonqi
Comment 1 Kevin Funk 2013-11-14 10:01:00 UTC
I'll have a look at this.
Comment 2 Milian Wolff 2013-11-14 10:13:26 UTC
Looks Kate/KDelibs related, can you reproduce it with plain Kate/Kwrite?
Comment 3 Kevin Funk 2013-11-21 09:36:00 UTC
Okay debugging further:
I've put a breakpoint on the KZoneAllocator destructor to check when it's passed. Now closing kdevelop yiels the following.
The static KZoneAllocator instance of KCompTreeNode is destructed during exit:
	kdecore.dll!KZoneAllocator::~KZoneAllocator()  Line 91	C++
 	kdeui.dll!_CRT_INIT(void * hDllHandle, unsigned long dwReason, void * lpreserved)  Line 415	C
 	kdeui.dll!__DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved)  Line 526 + 0x8 bytes	C
 	kdeui.dll!_DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved)  Line 476 + 0xe bytes	C
 	ntdll.dll!77b199a0() 	
 	[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]	
 	ntdll.dll!77b2d702() 	
 	ntdll.dll!77b2d5a4() 	
 	kernel32.dll!76f879c5() 	
 	msvcr100.dll!__crtExitProcess(int status)  Line 708 + 0x9 bytes	C
 	msvcr100.dll!doexit(int code, int quick, int retcaller)  Line 609	C
 	kdevelop.exe!WinMain(HINSTANCE__ * instance, HINSTANCE__ * prevInstance, char * __formal, int cmdShow)  Line 135 + 0x30 bytes	C++
 	kdevelop.exe!__tmainCRTStartup()  Line 518	C
 	ntdll.dll!77b19f72() 	
 	ntdll.dll!77b19f45() 	

The pointer to this KZoneAllocator instance: 
this	0x6af1657c {d=0x00fcb408 }	KZoneAllocator * const

Then, when continueing, I get a memory access fault here:
 	kdeui.dll!KCompTreeNode::remove(const QString & str)  Line 792 + 0x20 bytes	C++
 	kdeui.dll!KCompletion::removeItem(const QString & item)  Line 211 + 0x10 bytes	C++
 	katepartinterfaces.dll!KateCmd::unregisterCommand(KTextEditor::Command * cmd)  Line 71 + 0x6 bytes	C++
 	katepartinterfaces.dll!KateScriptManager::~KateScriptManager()  Line 55	C++
 	katepartinterfaces.dll!KateScriptManager::`scalar deleting destructor'()  + 0x8 bytes	C++
 	katepartinterfaces.dll!KateGlobal::~KateGlobal()  Line 225	C++
 	katepartinterfaces.dll!KateGlobal::`vector deleting destructor'()  + 0x3d bytes	C++
 	katepartinterfaces.dll!KateGlobal::decRef()  Line 222 + 0x26 bytes	C++
 	katepart.dll!KateFactory::`scalar deleting destructor'()  + 0x3c bytes	C++
 	QtCore4.dll!QObjectCleanupHandler::clear()  Line 139	C++
 	QtCore4.dll!QObjectCleanupHandler::~QObjectCleanupHandler()  Line 87	C++
 	kdecore.dll!QObjectCleanupHandler::`scalar deleting destructor'()  + 0x9 bytes	C++
 	kdecore.dll!_k_factorycleanup__LINE__::destroy()  Line 29 + 0x24 bytes	C++
 	kdecore.dll!_CRT_INIT(void * hDllHandle, unsigned long dwReason, void * lpreserved)  Line 415	C
 	kdecore.dll!__DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved)  Line 526 + 0x8 bytes	C
 	kdecore.dll!_DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved)  Line 476 + 0xe bytes	C
 	ntdll.dll!77b199a0() 	
 	[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]	
 	ntdll.dll!77b2d702() 	
 	ntdll.dll!77b2d5a4() 	
 	kernel32.dll!76f879c5() 	
 	msvcr100.dll!__crtExitProcess(int status)  Line 708 + 0x9 bytes	C
 	msvcr100.dll!doexit(int code, int quick, int retcaller)  Line 609	C
 	msvcr100.dll!exit(int code)  Line 393 + 0xc bytes	C
 	kdevelop.exe!__tmainCRTStartup()  Line 518	C
 	kernel32.dll!76f8336a() 	
 	ntdll.dll!77b19f72() 	
 	ntdll.dll!77b19f45() 	

Checking the members of this KCompTreeNode instance:
alloc	{d=0x00fcb408 }	KZoneAllocator

But this KZoneAllocator instance was already deleted before-hand => Crash.

So, the root problem is that KCompTreeNode's static KZoneAllocator member is deleted before KCompTreeNode is actually free'd. Can we do something about it?

If I understand correcty, the appropriate fix would be to delete KateFactory (i.e. unload the katepart plugin in KDevelop) earlier, before the atexit-handlers kick in. Milian?
Comment 4 Kevin Funk 2013-11-21 09:38:50 UTC
By the way, there was an attempt to fix this 3 years ago (https://bugs.kde.org/show_bug.cgi?id=243375, patch attached), but that patch got reverted because it broke other things.
Comment 5 Christoph Cullmann 2014-01-26 14:32:20 UTC
This is fixed now in KF5.
libktexteditor now manages the singleton KTextEditor::editor internally and it is cleanup up on QCoreApplication destruction, which should solve that issue once and for all.
(In addition more fixes went to the KZoneAllocator)
Comment 6 Kevin Funk 2014-01-27 08:00:56 UTC
FYI: I also fixed the root cause in KZoneAllocator and friends: https://git.reviewboard.kde.org/r/114715/ -- not yet decided which branche(s) (KF5 only, or both KF5 + kdelibs) this is pushed into, though.
Comment 7 Kevin Funk 2014-01-28 01:22:24 UTC
Git commit 8beb63bcb08568eac8578844d7a1f4f44280f685 by Kevin Funk.
Committed on 11/12/2013 at 09:48.
Pushed by kfunk into branch 'master'.

Attempt to fix KZoneAllocator issue

kcompletion.p_h: Make the static KZoneAllocator member of KCompTreeNode
a shared pointer so external users can hold a reference to it.

kcompletion.cpp: Hold a reference to KCompTreeNode's KZoneAllocator
instance so we avoid deleting the KZoneAllocator too early. See attached
bug report for possible causes. (Hint: It crashes on Windows because
~KZoneAllocator is called to early.)

kallocator.cpp: Use printf instead of qDebug(), because this code path
code might be called very late during destruction and qDebug() will
crash deep inside Qt.

Also see discussion:
http://lists.kde.org/?l=kde-devel&m=138583383708455&w=1
Related: bug 243375
REVIEW: 114715

M  +5    -3    kdecore/util/kallocator.cpp
M  +4    -1    kdeui/util/kcompletion.cpp
M  +11   -3    kdeui/util/kcompletion_p.h

http://commits.kde.org/kdelibs/8beb63bcb08568eac8578844d7a1f4f44280f685
Comment 8 Kevin Funk 2014-01-28 01:42:04 UTC
Git commit d10d52e0cc6b57f01dbe92a11eea94d0b12aa166 by Kevin Funk.
Committed on 28/01/2014 at 01:38.
Pushed by kfunk into branch 'master'.

Attempt to fix KZoneAllocator issue

kcompletion.p_h: Make the static KZoneAllocator member of KCompTreeNode
a shared pointer so external users can hold a reference to it.

kcompletion.cpp: Hold a reference to KCompTreeNode's KZoneAllocator
instance so we avoid deleting the KZoneAllocator too early. See attached
bug report for possible causes. (Hint: It crashes on Windows because
~KZoneAllocator is called to early.)

kallocator.cpp: Use printf instead of qDebug(), because this code path
code might be called very late during destruction and qDebug() will
crash deep inside Qt.

Also see discussion:
http://lists.kde.org/?l=kde-devel&m=138583383708455&w=1
Related: bug 243375
REVIEW: 114715

M  +4    -1    src/kcompletion.cpp
M  +11   -3    src/kcompletion_p.h
M  +5    -2    src/kzoneallocator.cpp

http://commits.kde.org/kcompletion/d10d52e0cc6b57f01dbe92a11eea94d0b12aa166
Comment 9 Albert Astals Cid 2014-02-10 19:37:32 UTC
Git commit c34045e2a2263865c825927de44c51faf5926132 by Albert Astals Cid, on behalf of Kevin Funk.
Committed on 11/12/2013 at 09:48.
Pushed by aacid into branch 'KDE/4.12'.

Attempt to fix KZoneAllocator issue

kcompletion.p_h: Make the static KZoneAllocator member of KCompTreeNode
a shared pointer so external users can hold a reference to it.

kcompletion.cpp: Hold a reference to KCompTreeNode's KZoneAllocator
instance so we avoid deleting the KZoneAllocator too early. See attached
bug report for possible causes. (Hint: It crashes on Windows because
~KZoneAllocator is called to early.)

kallocator.cpp: Use printf instead of qDebug(), because this code path
code might be called very late during destruction and qDebug() will
crash deep inside Qt.

Also see discussion:
http://lists.kde.org/?l=kde-devel&m=138583383708455&w=1
Related: bug 243375
REVIEW: 114715

M  +5    -3    kdecore/util/kallocator.cpp
M  +4    -1    kdeui/util/kcompletion.cpp
M  +11   -3    kdeui/util/kcompletion_p.h

http://commits.kde.org/kdelibs/c34045e2a2263865c825927de44c51faf5926132