Not long after upgrading to VS2010, my application won’t shut down cleanly. If I close the app and then hit pause in the IDE, I see this:

The problem is, there’s no context. The call stack just says [External code], which isn’t too helpful.
Here’s what I’ve done so far to try to narrow down the problem:
- deleted all extraneous plugins to minimize the number of worker threads launched
- set breakpoints in my code anywhere I create worker threads (and delegates + BeginInvoke, since I think they are labeled “Worker Thread” in the debugger anyway). None were hit.
- set IsBackground = true for all threads
While I could do the next brute force step, which is to roll my code back to a point where this didn’t happen and then look over all of the change logs, this isn’t terribly efficient. Can anyone recommend a better way to figure this out, given the notable lack of information presented by the debugger?
The only other things I can think of include:
- read up on WinDbg and try to use it to stop anytime a thread is started. At least, I thought that was possible… 🙂
- comment out huge blocks of code until the app closes properly, then start uncommenting until it doesn’t.
UPDATE
Perhaps this information will be of use. I decided to use WinDbg and attach to my application. I then closed it, and switched to thread 0 and dumped the stack contents. Here’s what I have:
ThreadCount: 6
UnstartedThread: 0
BackgroundThread: 1
PendingThread: 0
DeadThread: 4
Hosted Runtime: no
PreEmptive GC Alloc Lock
ID OSID ThreadOBJ State GC Context Domain Count APT Exception
0 1 1c70 005a65c8 6020 Enabled 02dac6e0:02dad7f8 005a03c0 0 STA
2 2 1b20 005b1980 b220 Enabled 00000000:00000000 005a03c0 0 MTA (Finalizer)
XXXX 3 08504048 19820 Enabled 00000000:00000000 005a03c0 0 Ukn
XXXX 4 08504540 19820 Enabled 00000000:00000000 005a03c0 0 Ukn
XXXX 5 08516a90 19820 Enabled 00000000:00000000 005a03c0 0 Ukn
XXXX 6 08517260 19820 Enabled 00000000:00000000 005a03c0 0 Ukn
0:008> ~0s
eax=c0674960 ebx=00000000 ecx=00000000 edx=00000000 esi=0040f320 edi=005a65c8
eip=76c37e47 esp=0040f23c ebp=0040f258 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
USER32!NtUserGetMessage+0x15:
76c37e47 83c404 add esp,4
0:000> !clrstack
OS Thread Id: 0x1c70 (0)
Child SP IP Call Site
0040f274 76c37e47 [InlinedCallFrame: 0040f274]
0040f270 6baa8976 DomainBoundILStubClass.IL_STUB_PInvoke(System.Windows.Interop.MSG ByRef, System.Runtime.InteropServices.HandleRef, Int32, Int32)*** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\WindowsBase\d17606e813f01376bd0def23726ecc62\WindowsBase.ni.dll
0040f274 6ba924c5 [InlinedCallFrame: 0040f274] MS.Win32.UnsafeNativeMethods.IntGetMessageW(System.Windows.Interop.MSG ByRef, System.Runtime.InteropServices.HandleRef, Int32, Int32)
0040f2c4 6ba924c5 MS.Win32.UnsafeNativeMethods.GetMessageW(System.Windows.Interop.MSG ByRef, System.Runtime.InteropServices.HandleRef, Int32, Int32)
0040f2dc 6ba8e5f8 System.Windows.Threading.Dispatcher.GetMessage(System.Windows.Interop.MSG ByRef, IntPtr, Int32, Int32)
0040f318 6ba8d579 System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame)
0040f368 6ba8d2a1 System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame)
0040f374 6ba7fba0 System.Windows.Threading.Dispatcher.Run()
0040f380 62e6ccbb System.Windows.Application.RunDispatcher(System.Object)*** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\PresentationFramewo#\7f91eecda3ff7ce478146b6458580c98\PresentationFramework.ni.dll
0040f38c 62e6c8ff System.Windows.Application.RunInternal(System.Windows.Window)
0040f3b0 62e6c682 System.Windows.Application.Run(System.Windows.Window)
0040f3c0 62e6c30b System.Windows.Application.Run()
0040f3cc 001f00bc MyApplication.App.Main() [C:\code\trunk\MyApplication\obj\Debug\GeneratedInternalTypeHelper.g.cs @ 24]
0040f608 66c421db [GCFrame: 0040f608]
EDIT — not sure if this helps, but the main thread’s call stack looks like this:
[Managed to Native Transition]
> WindowsBase.dll!MS.Win32.UnsafeNativeMethods.GetMessageW(ref System.Windows.Interop.MSG msg, System.Runtime.InteropServices.HandleRef hWnd, int uMsgFilterMin, int uMsgFilterMax) + 0x15 bytes
WindowsBase.dll!System.Windows.Threading.Dispatcher.GetMessage(ref System.Windows.Interop.MSG msg, System.IntPtr hwnd, int minMessage, int maxMessage) + 0x48 bytes
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame = {System.Windows.Threading.DispatcherFrame}) + 0x85 bytes
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame frame) + 0x49 bytes
WindowsBase.dll!System.Windows.Threading.Dispatcher.Run() + 0x4c bytes
PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore) + 0x17 bytes
PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window) + 0x6f bytes
PresentationFramework.dll!System.Windows.Application.Run(System.Windows.Window window) + 0x26 bytes
PresentationFramework.dll!System.Windows.Application.Run() + 0x1b bytes
I did a search on it and found some posts related to WPF GUIs hanging, and maybe that’ll give me some more clues.
The worker thread Id you are seeing is 0. This is a framework thread and is expected – it is not a thread that the program has “spawned”. If you attach to any .Net process you will see this. I’m not sure which framework thread it is – definitely not the finalizer thread as this is never thread 0. Perhaps a JIT thread?
What is more interesting then is your main thread, as this appears to be hanging. I would concentrate on debugging your main thread to bottom this out. Has it deadlocked itself from a window closed event handler waiting for something that will never happen for example?
Update
After reading the stack trace for the main thread added to the question, it would be interesting to run a test to bottom out whether the main thread is stalled or whether it is simply idle waiting for a message (and that it is waiting for a WM_CLOSE that it never received or was never sent).
The code below can be used to manually send a WM_CLOSE message to your application. Simply wait for your program to hang when you have shut it down, and then run the code. Replace the process name with your own.
Update 2
Ok, it looks like the main thread is well and truly hung as it is not processing WM_CLOSE or WM_QUIT messages.
Please try and make the smallest application that can reproduce the issue and post the code.
Example WM_CLOSE\WM_QUIT App