App lock on shutdown

F

Fredo

We have a problem with our app locking up on shutdown. It doesn't happen all
the time and it's not always easy to reproduce the problem.

I finally managed to reproduce it under WinDbg and have some information,
but I'm not entirely sure where the problem lies. I've removed all the
unmanaged threads from the output.

Something appears to be blocking the GC from cleaning up. Whatever triggers
the problem (we have ways to trigger it, but we don't know exactly what the
trigger is), causes the app to start leaking memory and objects like crazy
until it eventually crashes.

If the triggering event takes place and you try to shut down, the app locks
up in one of the Control.Dispose() calls that leads to
GC.WaitForPendingFinalizers() (see the first thread) and that's where it
hangs.

I think either Thread 5 or Thread 21 is the problem, but I'm not sure which.
I think it's Thread 21 (JuggerNET) which appears to be calling
WaitForPendingFinalizers() at the same time. On the other hand, Thread 5 is
in a Monitor.Wait() call.

Can someone give me some idea of how I might nail this down?

WinDbg dump follows:

Thanks.

Thread 0
ESP EIP
0x0012e1d0 0x7c90eb94 [FRAME: ECallMethodFrame] [DEFAULT] Void
System.GC.WaitForPendingFinalizers()
0x0012e1e0 0x799dbeb8 [DEFAULT] I8 System.GC.GetTotalMemory(Boolean)
0x0012e204 0x7b89787e [DEFAULT] [hasThis] Void
System.Windows.Forms.AxHost.ReleaseAxControl()
0x0012e22c 0x7b892ea4 [DEFAULT] [hasThis] Void
System.Windows.Forms.AxHost.TransitionDownTo(I4)
0x0012e254 0x7b8974a7 [DEFAULT] [hasThis] Void
System.Windows.Forms.AxHost.DisposeAxControls()
0x0012e25c 0x7b83317e [DEFAULT] [hasThis] Void
System.Windows.Forms.Control.DisposeAxControls()
0x0012e268 0x7b83317e [DEFAULT] [hasThis] Void
System.Windows.Forms.Control.DisposeAxControls()
0x0012e274 0x7b83317e [DEFAULT] [hasThis] Void
System.Windows.Forms.Control.DisposeAxControls()
0x0012e280 0x7b83317e [DEFAULT] [hasThis] Void
System.Windows.Forms.Control.DisposeAxControls()
0x0012e28c 0x7b83317e [DEFAULT] [hasThis] Void
System.Windows.Forms.Control.DisposeAxControls()
0x0012e298 0x7b83317e [DEFAULT] [hasThis] Void
System.Windows.Forms.Control.DisposeAxControls()
0x0012e2a4 0x7b83317e [DEFAULT] [hasThis] Void
System.Windows.Forms.Control.DisposeAxControls()
0x0012e2b0 0x7b83317e [DEFAULT] [hasThis] Void
System.Windows.Forms.Control.DisposeAxControls()
0x0012e2bc 0x7b832ee0 [DEFAULT] [hasThis] Void
System.Windows.Forms.Control.Dispose(Boolean)
0x0012e2fc 0x0f4a2240 [DEFAULT] [hasThis] Void
MyApp.Controls.ScrollableControl.Dispose(Boolean)
at [+0x208] [+0x132]
0x0012e350 0x0f4a201b [DEFAULT] [hasThis] Void
MyApp.Controls.ContainerControl.Dispose(Boolean)
at [+0x43] [+0x1f]
0x0012e368 0x0f48022e [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.ViewUserControl.Dispose(Boolean)
at [+0x126] [+0x93]
0x0012e398 0x0f4800f5 [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.ItemTypeViewBase.Dispose(Boolean)
at [+0x45] [+0x24]
0x0012e3b0 0x7b1da439 [DEFAULT] [hasThis] Void
System.ComponentModel.Component.Dispose()
0x0012e3c0 0x0f40ffa5 [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.ControllerBase.Dispose()
at [+0x365] [+0x1a8]
0x0012e40c 0x0f40f921 [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.ItemTypeControllerBase.Dispose()
at [+0x2f9] [+0x142]
0x0012e44c 0x0f40e7be [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.ControllerBase2.RemoveController(Class
MyApp.UI.Workspace.IController)
at [+0xa6] [+0x48]
0x0012e470 0x0f40e6c6 [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.PillarController.RemoveController(Class
MyApp.UI.Workspace.IController)
at [+0x1e] [+0x7]
0x0012e498 0x0f40e4e2 [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.PillarController.RemoveItemTypeInternal(Class
MyApp.UI.Model.IProject,Class MyApp.UI.Model.IItemType)
at [+0x15a] [+0x9b]
0x0012e4ec 0x0f40e371 [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.PillarController.RemoveItemType(Class
MyApp.UI.Model.IProject,Class MyApp.UI.Model.IItemType)
at [+0x19] [+0x8]
0x0012e508 0x0f40e330 [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.PillarController.HandleChildControllerClosed(Class
MyApp.UI.Workspace.IController)
at [+0x90] [+0x2b]
0x0012e540 0x0f40e289 [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.ControllerBase2.ChildControllerClosed(Object,Class
System.EventArgs)
at [+0x21] [+0xc]
0x0012e55c 0x0f40e24a [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.ControllerBase.OnClosed(Class System.EventArgs)
at [+0x22] [+0x15]
0x0012e578 0x0f40d9a6 [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.ControllerBase.Close()
at [+0x1e6] [+0xe9]
0x0012e5ac 0x0f40d6cf [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.ItemTypeControllerBase.Close()
at [+0x7f] [+0x39]
0x0012e5dc 0x0f40d56f [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.PillarController.CloseProject(Class
MyApp.UI.Model.IProject)
at [+0xd7] [+0x40]
0x0012e618 0x0f40d423 [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.ProjectController.Close()
at [+0xdb] [+0x50]
0x0012e648 0x0f40d22f [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.WorkbenchWindowController.CloseProject(Class
MyApp.UI.Model.IProject)
at [+0x7f] [+0x3c]
0x0012e678 0x0f40d18c [DEFAULT] Void
MyApp.UI.Projects.CloseProjectAction.CloseProjects(SZArray Class
MyApp.UI.Workspace.IProjectController)
at [+0x74] [+0x1f]
0x0012e6a8 0x0f40c998 [DEFAULT] [hasThis] Void
MyApp.UI.Projects.CloseProjectAction.OnExecute(Class System.EventArgs)
at [+0x600] [+0x24b]
0x0012e7c4 0x0f163e0b [DEFAULT] [hasThis] Void
MyApp.Commands.Action.FireExecute()
at [+0x23] [+0x13]
0x0012e7d8 0x0f40c17c [DEFAULT] [hasThis] Void
MyApp.UI.Actions.AppSaveAction.OnExecute(Class System.EventArgs)
at [+0x104] [+0x6b]
0x0012e810 0x0f163e0b [DEFAULT] [hasThis] Void
MyApp.Commands.Action.FireExecute()
at [+0x23] [+0x13]
0x0012e824 0x0f40bf8f [DEFAULT] [hasThis] Void
MyApp.UI.Security.LogoutAction.OnExecute(Class System.EventArgs)
at [+0x57] [+0x13]
0x0012e85c 0x0f163e0b [DEFAULT] [hasThis] Void
MyApp.Commands.Action.FireExecute()
at [+0x23] [+0x13]
0x0012e870 0x0f40a931 [DEFAULT] [hasThis] Boolean
MyApp.UI.Workspace.WorkbenchWindowController.CloseWorkbenchWindow(Boolean)
at [+0x109] [+0x5d]
0x0012e89c 0x0f40a7fb [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.WorkbenchWindowController.WorkbenchWindowClosing(Object,Class
System.ComponentModel.CancelEventArgs)
at [+0x1b] [+0x0]
0x0012e8bc 0x7b8fc91d [DEFAULT] [hasThis] Void
System.Windows.Forms.Form.OnClosing(Class
System.ComponentModel.CancelEventArgs)
0x0012e8c8 0x7b8fe0d4 [DEFAULT] [hasThis] Void
System.Windows.Forms.Form.WmClose(ByRef ValueClass
System.Windows.Forms.Message)
0x0012e8e4 0x7b822adc [DEFAULT] [hasThis] Void
System.Windows.Forms.Form.WndProc(ByRef ValueClass
System.Windows.Forms.Message)
0x0012e8f4 0x0e1197b5 [DEFAULT] [hasThis] Void
MyApp.MFace.ControlledForm.WndProc(ByRef ValueClass
System.Windows.Forms.Message)
at [+0x1cd] [+0xf6]
0x0012e960 0x0e11a47a [DEFAULT] [hasThis] Void
MyApp.UI.WorkbenchWindow.WndProc(ByRef ValueClass
System.Windows.Forms.Message)
at [+0x1fa] [+0xfa]
0x0012e9a0 0x7b82293b [DEFAULT] [hasThis] Void
System.Windows.Forms.Control/ControlNativeWindow.OnMessage(ByRef ValueClass
System.Windows.Forms.Message)
0x0012e9a4 0x7b82291c [DEFAULT] [hasThis] Void
System.Windows.Forms.Control/ControlNativeWindow.WndProc(ByRef ValueClass
System.Windows.Forms.Message)
0x0012e9b4 0x7b8227c0 [DEFAULT] [hasThis] I
System.Windows.Forms.NativeWindow.Callback(I,I4,I,I)
0x0012ed74 0x00bc8ac2 [FRAME: NDirectMethodFrameStandalone] [DEFAULT] I
System.Windows.Forms.UnsafeNativeMethods.SendMessage(ValueClass
System.Runtime.InteropServices.HandleRef,I4,I4,I4)
0x0012ed88 0x7b823d0a [DEFAULT] [hasThis] I
System.Windows.Forms.Control.SendMessage(I4,I4,I4)
0x0012ee60 0x01112638 [FRAME: InlinedCallFrame]
0x0012f34c 0x01112638 [FRAME: NDirectMethodFrameStandalone] [DEFAULT] I
System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(ByRef ValueClass
MSG)
0x0012f35c 0x7b82df5a [DEFAULT] [hasThis] Boolean
System.Windows.Forms.Application/ComponentManager.System.Windows.Forms.UnsafeNativeMethods+IMsoComponentManager.FPushMessageLoop(I4,I4,I4)
0x0012f3f4 0x7b82daca [DEFAULT] [hasThis] Void
System.Windows.Forms.Application/ThreadContext.RunMessageLoopInner(I4,Class
System.Windows.Forms.ApplicationContext)
0x0012f430 0x7b82d7e5 [DEFAULT] [hasThis] Void
System.Windows.Forms.Application/ThreadContext.RunMessageLoop(I4,Class
System.Windows.Forms.ApplicationContext)
0x0012f45c 0x7b87cba1 [DEFAULT] Void
System.Windows.Forms.Application.Run(Class
System.Windows.Forms.ApplicationContext)
0x0012f464 0x03ad4c1a [DEFAULT] [hasThis] Void MyApp.UI.Workbench.Run()
at [+0x32a] [+0x18b]
0x0012f4b4 0x030de9e7 [DEFAULT] Void
MyApp.Platform.ApplicationController.StartApplication(String)
at [+0x58f] [+0x1bc]
0x0012f5ac 0x030dc72b [DEFAULT] [hasThis] Void MyApp.MyApp.StartApp()
at [+0x40b] [+0x1f5]
E:\Ascential\Clearcase\davisp_m81\MyApp\src\MyApp.cs:16707566
0x0012f638 0x030d5afb [DEFAULT] [hasThis] Void MyApp.MyApp.Run(SZArray
String)
at [+0x1f3] [+0xe8]
E:\Ascential\Clearcase\davisp_m81\MyApp\src\MyApp.cs:617
0x0012f68c 0x030d016c [DEFAULT] Void MyApp.MyApp.Main(SZArray String)
at [+0xc4] [+0x6b]
E:\Ascential\Clearcase\davisp_m81\MyApp\src\MyApp.cs:273
0x0012f8b0 0x791dc474 [FRAME: GCFrame]
0x0012f9b0 0x791dc474 [FRAME: GCFrame]
0x0012fa94 0x791dc474 [FRAME: GCFrame]
Thread 1
ESP EIP

Thread 5
ESP EIP
0x092cf754 0x7c90eb94 [FRAME: GCFrame]
0x092cf800 0x7c90eb94 [FRAME: ECallMethodFrame] [DEFAULT] Boolean
System.Threading.Monitor.ObjWait(Boolean,I4,Object)
0x092cf814 0x79a29899 [DEFAULT] Boolean
System.Threading.Monitor.Wait(Object,I4,Boolean)
0x092cf820 0x79a29988 [DEFAULT] Boolean
System.Threading.Monitor.Wait(Object,I4)
0x092cf824 0x034049d5 [DEFAULT] Boolean
MyApp.Common.SynchronizationUtil.MonitorWait(Object,I4)
at [+0xa5] [+0x38]
E:\Ascential\Clearcase\davisp_m81\MyApp\Modules\MyApp.Platform\src\Common\SynchronizationUtil.cs:262
0x092cf868 0x03403ddc [DEFAULT] [hasThis] Void
MyApp.UI.StatusBar.SchedulingStatusBarModel.RunUpdates()
at [+0x16c] [+0x51]
0x092cfb40 0x791dc474 [FRAME: GCFrame]


Thread 21
ESP EIP
0x0884faa4 0x7c90eb94 [FRAME: ECallMethodFrame] [DEFAULT] Void
System.GC.WaitForPendingFinalizers()
0x0884fab4 0x074b5eba [DEFAULT] Void
Codemesh.JuggerNET.NativeInterface.RunFinalizers()
at [+0x12] [+0xc]
0x0884fcc0 0x791dc474 [FRAME: GCFrame]

Thread 31
ESP EIP
0x0adcf92c 0x7c90eb94 [FRAME: ECallMethodFrame] [DEFAULT] Void
System.Threading.Thread.Sleep(I4)
0x0adcf93c 0x033f9151 [DEFAULT] [hasThis] Void
MyApp.Platform.Session.ServerSession.Heartbeat()
at [+0x49] [+0x12]
0x0adcfbc0 0x791dc474 [FRAME: GCFrame]

Thread 32
ESP EIP
0x0e0ff804 0x7c90eb94 [FRAME: ECallMethodFrame] [DEFAULT] Void
System.Threading.Thread.Sleep(I4)
0x0e0ff814 0x0dfd61f6 [DEFAULT] [hasThis] Void
MyApp.UI.StatusBar.MyAppStatusBar.Run()
at [+0x86] [+0x2e]
0x0e0ffac0 0x791dc474 [FRAME: GCFrame]
 
W

Willy Denoyette [MVP]

It looks like the finalizer thread is blocked. You'll have to look at it's
call stack in order to know what he's doing.

Willy.

Fredo said:
We have a problem with our app locking up on shutdown. It doesn't happen
all the time and it's not always easy to reproduce the problem.

I finally managed to reproduce it under WinDbg and have some information,
but I'm not entirely sure where the problem lies. I've removed all the
unmanaged threads from the output.

Something appears to be blocking the GC from cleaning up. Whatever
triggers the problem (we have ways to trigger it, but we don't know
exactly what the trigger is), causes the app to start leaking memory and
objects like crazy until it eventually crashes.

If the triggering event takes place and you try to shut down, the app
locks up in one of the Control.Dispose() calls that leads to
GC.WaitForPendingFinalizers() (see the first thread) and that's where it
hangs.

I think either Thread 5 or Thread 21 is the problem, but I'm not sure
which. I think it's Thread 21 (JuggerNET) which appears to be calling
WaitForPendingFinalizers() at the same time. On the other hand, Thread 5
is in a Monitor.Wait() call.

Can someone give me some idea of how I might nail this down?

WinDbg dump follows:

Thanks.

Thread 0
ESP EIP
0x0012e1d0 0x7c90eb94 [FRAME: ECallMethodFrame] [DEFAULT] Void
System.GC.WaitForPendingFinalizers()
0x0012e1e0 0x799dbeb8 [DEFAULT] I8 System.GC.GetTotalMemory(Boolean)
0x0012e204 0x7b89787e [DEFAULT] [hasThis] Void
System.Windows.Forms.AxHost.ReleaseAxControl()
0x0012e22c 0x7b892ea4 [DEFAULT] [hasThis] Void
System.Windows.Forms.AxHost.TransitionDownTo(I4)
0x0012e254 0x7b8974a7 [DEFAULT] [hasThis] Void
System.Windows.Forms.AxHost.DisposeAxControls()
0x0012e25c 0x7b83317e [DEFAULT] [hasThis] Void
System.Windows.Forms.Control.DisposeAxControls()
0x0012e268 0x7b83317e [DEFAULT] [hasThis] Void
System.Windows.Forms.Control.DisposeAxControls()
0x0012e274 0x7b83317e [DEFAULT] [hasThis] Void
System.Windows.Forms.Control.DisposeAxControls()
0x0012e280 0x7b83317e [DEFAULT] [hasThis] Void
System.Windows.Forms.Control.DisposeAxControls()
0x0012e28c 0x7b83317e [DEFAULT] [hasThis] Void
System.Windows.Forms.Control.DisposeAxControls()
0x0012e298 0x7b83317e [DEFAULT] [hasThis] Void
System.Windows.Forms.Control.DisposeAxControls()
0x0012e2a4 0x7b83317e [DEFAULT] [hasThis] Void
System.Windows.Forms.Control.DisposeAxControls()
0x0012e2b0 0x7b83317e [DEFAULT] [hasThis] Void
System.Windows.Forms.Control.DisposeAxControls()
0x0012e2bc 0x7b832ee0 [DEFAULT] [hasThis] Void
System.Windows.Forms.Control.Dispose(Boolean)
0x0012e2fc 0x0f4a2240 [DEFAULT] [hasThis] Void
MyApp.Controls.ScrollableControl.Dispose(Boolean)
at [+0x208] [+0x132]
0x0012e350 0x0f4a201b [DEFAULT] [hasThis] Void
MyApp.Controls.ContainerControl.Dispose(Boolean)
at [+0x43] [+0x1f]
0x0012e368 0x0f48022e [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.ViewUserControl.Dispose(Boolean)
at [+0x126] [+0x93]
0x0012e398 0x0f4800f5 [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.ItemTypeViewBase.Dispose(Boolean)
at [+0x45] [+0x24]
0x0012e3b0 0x7b1da439 [DEFAULT] [hasThis] Void
System.ComponentModel.Component.Dispose()
0x0012e3c0 0x0f40ffa5 [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.ControllerBase.Dispose()
at [+0x365] [+0x1a8]
0x0012e40c 0x0f40f921 [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.ItemTypeControllerBase.Dispose()
at [+0x2f9] [+0x142]
0x0012e44c 0x0f40e7be [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.ControllerBase2.RemoveController(Class
MyApp.UI.Workspace.IController)
at [+0xa6] [+0x48]
0x0012e470 0x0f40e6c6 [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.PillarController.RemoveController(Class
MyApp.UI.Workspace.IController)
at [+0x1e] [+0x7]
0x0012e498 0x0f40e4e2 [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.PillarController.RemoveItemTypeInternal(Class
MyApp.UI.Model.IProject,Class MyApp.UI.Model.IItemType)
at [+0x15a] [+0x9b]
0x0012e4ec 0x0f40e371 [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.PillarController.RemoveItemType(Class
MyApp.UI.Model.IProject,Class MyApp.UI.Model.IItemType)
at [+0x19] [+0x8]
0x0012e508 0x0f40e330 [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.PillarController.HandleChildControllerClosed(Class
MyApp.UI.Workspace.IController)
at [+0x90] [+0x2b]
0x0012e540 0x0f40e289 [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.ControllerBase2.ChildControllerClosed(Object,Class
System.EventArgs)
at [+0x21] [+0xc]
0x0012e55c 0x0f40e24a [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.ControllerBase.OnClosed(Class System.EventArgs)
at [+0x22] [+0x15]
0x0012e578 0x0f40d9a6 [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.ControllerBase.Close()
at [+0x1e6] [+0xe9]
0x0012e5ac 0x0f40d6cf [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.ItemTypeControllerBase.Close()
at [+0x7f] [+0x39]
0x0012e5dc 0x0f40d56f [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.PillarController.CloseProject(Class
MyApp.UI.Model.IProject)
at [+0xd7] [+0x40]
0x0012e618 0x0f40d423 [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.ProjectController.Close()
at [+0xdb] [+0x50]
0x0012e648 0x0f40d22f [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.WorkbenchWindowController.CloseProject(Class
MyApp.UI.Model.IProject)
at [+0x7f] [+0x3c]
0x0012e678 0x0f40d18c [DEFAULT] Void
MyApp.UI.Projects.CloseProjectAction.CloseProjects(SZArray Class
MyApp.UI.Workspace.IProjectController)
at [+0x74] [+0x1f]
0x0012e6a8 0x0f40c998 [DEFAULT] [hasThis] Void
MyApp.UI.Projects.CloseProjectAction.OnExecute(Class System.EventArgs)
at [+0x600] [+0x24b]
0x0012e7c4 0x0f163e0b [DEFAULT] [hasThis] Void
MyApp.Commands.Action.FireExecute()
at [+0x23] [+0x13]
0x0012e7d8 0x0f40c17c [DEFAULT] [hasThis] Void
MyApp.UI.Actions.AppSaveAction.OnExecute(Class System.EventArgs)
at [+0x104] [+0x6b]
0x0012e810 0x0f163e0b [DEFAULT] [hasThis] Void
MyApp.Commands.Action.FireExecute()
at [+0x23] [+0x13]
0x0012e824 0x0f40bf8f [DEFAULT] [hasThis] Void
MyApp.UI.Security.LogoutAction.OnExecute(Class System.EventArgs)
at [+0x57] [+0x13]
0x0012e85c 0x0f163e0b [DEFAULT] [hasThis] Void
MyApp.Commands.Action.FireExecute()
at [+0x23] [+0x13]
0x0012e870 0x0f40a931 [DEFAULT] [hasThis] Boolean
MyApp.UI.Workspace.WorkbenchWindowController.CloseWorkbenchWindow(Boolean)
at [+0x109] [+0x5d]
0x0012e89c 0x0f40a7fb [DEFAULT] [hasThis] Void
MyApp.UI.Workspace.WorkbenchWindowController.WorkbenchWindowClosing(Object,Class
System.ComponentModel.CancelEventArgs)
at [+0x1b] [+0x0]
0x0012e8bc 0x7b8fc91d [DEFAULT] [hasThis] Void
System.Windows.Forms.Form.OnClosing(Class
System.ComponentModel.CancelEventArgs)
0x0012e8c8 0x7b8fe0d4 [DEFAULT] [hasThis] Void
System.Windows.Forms.Form.WmClose(ByRef ValueClass
System.Windows.Forms.Message)
0x0012e8e4 0x7b822adc [DEFAULT] [hasThis] Void
System.Windows.Forms.Form.WndProc(ByRef ValueClass
System.Windows.Forms.Message)
0x0012e8f4 0x0e1197b5 [DEFAULT] [hasThis] Void
MyApp.MFace.ControlledForm.WndProc(ByRef ValueClass
System.Windows.Forms.Message)
at [+0x1cd] [+0xf6]
0x0012e960 0x0e11a47a [DEFAULT] [hasThis] Void
MyApp.UI.WorkbenchWindow.WndProc(ByRef ValueClass
System.Windows.Forms.Message)
at [+0x1fa] [+0xfa]
0x0012e9a0 0x7b82293b [DEFAULT] [hasThis] Void
System.Windows.Forms.Control/ControlNativeWindow.OnMessage(ByRef
ValueClass System.Windows.Forms.Message)
0x0012e9a4 0x7b82291c [DEFAULT] [hasThis] Void
System.Windows.Forms.Control/ControlNativeWindow.WndProc(ByRef ValueClass
System.Windows.Forms.Message)
0x0012e9b4 0x7b8227c0 [DEFAULT] [hasThis] I
System.Windows.Forms.NativeWindow.Callback(I,I4,I,I)
0x0012ed74 0x00bc8ac2 [FRAME: NDirectMethodFrameStandalone] [DEFAULT] I
System.Windows.Forms.UnsafeNativeMethods.SendMessage(ValueClass
System.Runtime.InteropServices.HandleRef,I4,I4,I4)
0x0012ed88 0x7b823d0a [DEFAULT] [hasThis] I
System.Windows.Forms.Control.SendMessage(I4,I4,I4)
0x0012ee60 0x01112638 [FRAME: InlinedCallFrame]
0x0012f34c 0x01112638 [FRAME: NDirectMethodFrameStandalone] [DEFAULT] I
System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(ByRef ValueClass
MSG)
0x0012f35c 0x7b82df5a [DEFAULT] [hasThis] Boolean
System.Windows.Forms.Application/ComponentManager.System.Windows.Forms.UnsafeNativeMethods+IMsoComponentManager.FPushMessageLoop(I4,I4,I4)
0x0012f3f4 0x7b82daca [DEFAULT] [hasThis] Void
System.Windows.Forms.Application/ThreadContext.RunMessageLoopInner(I4,Class
System.Windows.Forms.ApplicationContext)
0x0012f430 0x7b82d7e5 [DEFAULT] [hasThis] Void
System.Windows.Forms.Application/ThreadContext.RunMessageLoop(I4,Class
System.Windows.Forms.ApplicationContext)
0x0012f45c 0x7b87cba1 [DEFAULT] Void
System.Windows.Forms.Application.Run(Class
System.Windows.Forms.ApplicationContext)
0x0012f464 0x03ad4c1a [DEFAULT] [hasThis] Void MyApp.UI.Workbench.Run()
at [+0x32a] [+0x18b]
0x0012f4b4 0x030de9e7 [DEFAULT] Void
MyApp.Platform.ApplicationController.StartApplication(String)
at [+0x58f] [+0x1bc]
0x0012f5ac 0x030dc72b [DEFAULT] [hasThis] Void MyApp.MyApp.StartApp()
at [+0x40b] [+0x1f5]
E:\Ascential\Clearcase\davisp_m81\MyApp\src\MyApp.cs:16707566
0x0012f638 0x030d5afb [DEFAULT] [hasThis] Void MyApp.MyApp.Run(SZArray
String)
at [+0x1f3] [+0xe8]
E:\Ascential\Clearcase\davisp_m81\MyApp\src\MyApp.cs:617
0x0012f68c 0x030d016c [DEFAULT] Void MyApp.MyApp.Main(SZArray String)
at [+0xc4] [+0x6b]
E:\Ascential\Clearcase\davisp_m81\MyApp\src\MyApp.cs:273
0x0012f8b0 0x791dc474 [FRAME: GCFrame]
0x0012f9b0 0x791dc474 [FRAME: GCFrame]
0x0012fa94 0x791dc474 [FRAME: GCFrame]
Thread 1
ESP EIP

Thread 5
ESP EIP
0x092cf754 0x7c90eb94 [FRAME: GCFrame]
0x092cf800 0x7c90eb94 [FRAME: ECallMethodFrame] [DEFAULT] Boolean
System.Threading.Monitor.ObjWait(Boolean,I4,Object)
0x092cf814 0x79a29899 [DEFAULT] Boolean
System.Threading.Monitor.Wait(Object,I4,Boolean)
0x092cf820 0x79a29988 [DEFAULT] Boolean
System.Threading.Monitor.Wait(Object,I4)
0x092cf824 0x034049d5 [DEFAULT] Boolean
MyApp.Common.SynchronizationUtil.MonitorWait(Object,I4)
at [+0xa5] [+0x38]
E:\Ascential\Clearcase\davisp_m81\MyApp\Modules\MyApp.Platform\src\Common\SynchronizationUtil.cs:262
0x092cf868 0x03403ddc [DEFAULT] [hasThis] Void
MyApp.UI.StatusBar.SchedulingStatusBarModel.RunUpdates()
at [+0x16c] [+0x51]
0x092cfb40 0x791dc474 [FRAME: GCFrame]


Thread 21
ESP EIP
0x0884faa4 0x7c90eb94 [FRAME: ECallMethodFrame] [DEFAULT] Void
System.GC.WaitForPendingFinalizers()
0x0884fab4 0x074b5eba [DEFAULT] Void
Codemesh.JuggerNET.NativeInterface.RunFinalizers()
at [+0x12] [+0xc]
0x0884fcc0 0x791dc474 [FRAME: GCFrame]

Thread 31
ESP EIP
0x0adcf92c 0x7c90eb94 [FRAME: ECallMethodFrame] [DEFAULT] Void
System.Threading.Thread.Sleep(I4)
0x0adcf93c 0x033f9151 [DEFAULT] [hasThis] Void
MyApp.Platform.Session.ServerSession.Heartbeat()
at [+0x49] [+0x12]
0x0adcfbc0 0x791dc474 [FRAME: GCFrame]

Thread 32
ESP EIP
0x0e0ff804 0x7c90eb94 [FRAME: ECallMethodFrame] [DEFAULT] Void
System.Threading.Thread.Sleep(I4)
0x0e0ff814 0x0dfd61f6 [DEFAULT] [hasThis] Void
MyApp.UI.StatusBar.MyAppStatusBar.Run()
at [+0x86] [+0x2e]
0x0e0ffac0 0x791dc474 [FRAME: GCFrame]
 
F

Fredo

Willy Denoyette said:
It looks like the finalizer thread is blocked. You'll have to look at it's
call stack in order to know what he's doing.

Willy.

Willy, yes, it does appear so. I performed the triggering event and then got
stack information before trying to shutdown the app. At this point, our app
is leaking like a sieve because the GC is blocked, but the app is still
running "apparently" normally (though obviously leaking).

The managed threads info is here:

ThreadCount: 11
UnstartedThread: 0
BackgroundThread: 4
PendingThread: 0
DeadThread: 5
PreEmptive GC Alloc
Lock
ID ThreadOBJ State GC Context Domain
Count APT Exception
0 0xe34 0x0014a760 0x6020 Enabled 0x00000000:0x00000000 0x0015c240
0 STA
1 0xdd8 0x00153228 0xb220 Enabled 0x00000000:0x00000000 0x0015c240
0 MTA (Finalizer)
21 0x658 0x082666f8 0x2001220 Enabled 0x00000000:0x00000000 0x0015c240
0 Ukn
XXX 0 0x081868b0 0x1820 Enabled 0x00000000:0x00000000 0x0015c240
0 Ukn
29 0xd10 0x08cde780 0x2001220 Enabled 0x00000000:0x00000000 0x0015c240
0 Ukn
5 0xfdc 0x081f0ba8 0x2001220 Enabled 0x00000000:0x00000000 0x0015c240
0 Ukn
30 0xd40 0x07436a00 0x2001020 Enabled 0x00000000:0x00000000 0x0015c240
0 Ukn
XXX 0 0x0978f5d0 0x1820 Enabled 0x00000000:0x00000000 0x0015c240
0 Ukn
XXX 0 0x09d461b8 0xb820 Enabled 0x00000000:0x00000000 0x0015c240
0 Ukn
XXX 0 0x09d26338 0x1820 Enabled 0x00000000:0x00000000 0x0015c240
0 Ukn
XXX 0 0x09d26d98 0x1820 Enabled 0x00000000:0x00000000 0x0015c240
0 Ukn

As you can see, Thread 1 is the GC in an MTA and Thread 0 is the main app
thread in an STA.

The unmanaged callstack for the GC thread is here:

1 Id: e38.dd8 Suspend: 1 Teb: 7ffdd000 Unfrozen
ChildEBP RetAddr Args to Child
02f3f66c 7c90e9c0 7c8025cb 000004c8 00000000 ntdll!KiFastSystemCallRet
02f3f670 7c8025cb 000004c8 00000000 00000000 ntdll!ZwWaitForSingleObject+0xc
02f3f6d4 7c802532 000004c8 ffffffff 00000000
KERNEL32!WaitForSingleObjectEx+0xa8
02f3f6e8 7752abbd 000004c8 ffffffff 001ba128
KERNEL32!WaitForSingleObject+0x12
02f3f704 77601e51 001ba128 00213a60 00000000 ole32!GetToSTA+0x6f
02f3f724 7760109a 02f3f7ec 02f3f8fc 001ba6e0
ole32!CRpcChannelBuffer::SwitchAptAndDispatchCall+0xf6
02f3f804 7751047c 001ba6e0 02f3f8fc 02f3f8ec
ole32!CRpcChannelBuffer::SendReceive2+0xb9
02f3f870 775265b5 001ba6e0 02f3f8fc 02f3f8ec
ole32!CAptRpcChnl::SendReceive+0xab
02f3f8c4 77ef4db5 00000001 02f3f8fc 02f3f8ec
ole32!CCtxComChnl::SendReceive+0x91
02f3f8e0 77ef4ead 09907014 02f3f928 0600015b RPCRT4!NdrProxySendReceive+0x43
02f3fcbc 77ef4e42 774e6218 774e95d6 02f3fcf4 RPCRT4!NdrClientCall2+0x1fa
02f3fcdc 77e8a453 0000000c 00000008 02f3fd74
RPCRT4!ObjectStublessClient+0x8b
02f3fcec 77526191 09907014 02f3fd28 00000000 RPCRT4!ObjectStubless+0xf
02f3fd74 7758a7c6 0016be08 79208811 02f3fe0c
ole32!CObjectContext::InternalContextCallback+0x122
02f3fdc4 79206f4e 0016be18 79208811 02f3fe0c
ole32!CObjectContext::ContextCallback+0x85
02f3fe70 79208031 79208848 0376b118 00000000
mscorwks!CtxEntry::EnterContext+0xb7
02f3fe98 792070c7 00000000 793eefb8 00000000
mscorwks!ComPlusApartmentCleanupGroup::CleanUpWrappers+0x63
02f3fed0 79216d5d 7c80a017 00000000 792167fb
mscorwks!ComPlusWrapperCleanupList::CleanUpWrappers+0x69
02f3fedc 792167fb 791b9974 00000000 791d0bab
mscorwks!SyncBlockCache::CleanupSyncBlocks+0x85
02f3fee0 791b9974 00000000 791d0bab 001533f0
mscorwks!Thread::DoExtraWorkForFinalizer+0x23

As you can see in the ole32!GetToSTA, the GC is trying to get to the STA
thread to dispose of some COM object. Basically, the thread is just stuck
there and not doing anything. I would think that would mean that the STA
thread (thread 0) is hung as well, but in this case, Thread 0 is not hung.

The managed callstack for Thread0 at the same time is this:

Thread 0
ESP EIP
0x0012f374 0x7c90eb94 [FRAME: InlinedCallFrame]
0x0012f35c 0x7b82e116 [DEFAULT] [hasThis] Boolean
System.Windows.Forms.Application/ComponentManager.System.Windows.Forms.UnsafeNativeMethods+IMsoComponentManager.FPushMessageLoop(I4,I4,I4)
0x0012f3f4 0x7b82daca [DEFAULT] [hasThis] Void
System.Windows.Forms.Application/ThreadContext.RunMessageLoopInner(I4,Class
System.Windows.Forms.ApplicationContext)
0x0012f430 0x7b82d7e5 [DEFAULT] [hasThis] Void
System.Windows.Forms.Application/ThreadContext.RunMessageLoop(I4,Class
System.Windows.Forms.ApplicationContext)
0x0012f45c 0x7b87cba1 [DEFAULT] Void
System.Windows.Forms.Application.Run(Class
System.Windows.Forms.ApplicationContext)
0x0012f464 0x03b24622 [DEFAULT] [hasThis] Void MyApp.UI.Workbench.Run()
at [+0x32a] [+0x18b]
0x0012f4b4 0x030df137 [DEFAULT] Void
MyApp.Platform.ApplicationController.StartApplication(String)
at [+0x58f] [+0x1bc]
0x0012f5ac 0x030dc953 [DEFAULT] [hasThis] Void MyApp.MyApp.StartApp()
at [+0x40b] [+0x1f5]
E:\Ascential\Clearcase\davisp_m81\MyApp\src\MyApp.cs:16707566
0x0012f638 0x030d2864 [DEFAULT] [hasThis] Void MyApp.MyApp.Run(SZArray
String)
at [+0x1f4] [+0xe8]
E:\Ascential\Clearcase\davisp_m81\MyApp\src\MyApp.cs:617
0x0012f68c 0x030d016c [DEFAULT] Void MyApp.MyApp.Main(SZArray String)
at [+0xc4] [+0x6b]
E:\Ascential\Clearcase\davisp_m81\MyApp\src\MyApp.cs:273
0x0012f8b0 0x791dc474 [FRAME: GCFrame]
0x0012f9b0 0x791dc474 [FRAME: GCFrame]
0x0012fa94 0x791dc474 [FRAME: GCFrame]

So the STA thread is pumping the message loop. So why can't the GC get to
the STA thread?

Thread 21 is the JuggerNET GC thread and it has this unmanaged callstack:

21 Id: e38.658 Suspend: 1 Teb: 7ffa5000 Unfrozen
ChildEBP RetAddr Args to Child
0875f92c 7c90e9ab 7c8094e2 00000001 0875f958 ntdll!KiFastSystemCallRet
0875f930 7c8094e2 00000001 0875f958 00000001
ntdll!ZwWaitForMultipleObjects+0xc
0875f9cc 7929b344 00000001 793e2df8 00000000
KERNEL32!WaitForMultipleObjectsEx+0x12c
0875f9fc 7929b8a5 00000001 793e2df8 00000000
mscorwks!Thread::DoAppropriateWaitWorker+0xc1
0875fa50 79265e5c 00000001 793e2df8 00000000
mscorwks!Thread::DoAppropriateWait+0x46
0875fa78 79218d41 ffffffff 035b2e17 0875fa8c
mscorwks!GCHeap::FinalizerThreadWait+0x76
0875fab4 791dc474 0875fbcc 791dce6f 0875fb08
mscorwks!GCInterface::RunFinalizers+0x7
0875faec 791d8b62 00000000 00000000 0875fbcc mscorwks!CallDescrWorker+0x30
0875fafc 791dcd61 791dcd71 79bca8cb 79b7c000
mscorwks!MetaSig::SizeOfActualFixedArgStack+0x14
0875fbcc 791ddb14 00bca8cb 79b7c000 0875fbf8
mscorwks!MethodDesc::CallDescr+0x79
0875fc88 791ddb82 79bca8cb 79b7c000 79b93e78
mscorwks!MethodDesc::CallDescr+0x4f
0875fcb0 792ea4af 0875fcf4 082666f8 791b33f8 mscorwks!MethodDesc::Call+0x97
0875fcfc 792ea57e 0875fd14 0807ad40 792ea4bc
mscorwks!ThreadNative::KickOffThread_Worker+0x9d
0875fda0 791c94b4 0807ad40 804fd2b8 00000100
mscorwks!ThreadNative::KickOffThread+0xc2
0875ffb4 7c80b683 08059fe8 00000000 082668c0
mscorwks!Thread::intermediateThreadProc+0x44
0875ffec 00000000 791c9473 08059fe8 00000000 KERNEL32!BaseThreadStart+0x37

Could this be blocking the regular GC thread?

Thanks.
 
F

Fredo

I have a possible theory:

Our application uses a number of custom controls. We have probably 50 or so
custom controls of various types. I don't know how many places we override
WndProc, but it's a lot.

For the GC to get to the STA thread, it has to do a MarshaledInvoke which
would come through via the registered window message .NET assigned to the
job. I'm guessing it's possible that, somewhere, in any of our many
WndProcs, that somewhere we're intercepting the message and it's getting
lost. Does that seem like a viable possibility? Does anyone know how we
might find out how that's happening?

Thanks.
 
W

Willy Denoyette [MVP]

Fredo said:
Willy, yes, it does appear so. I performed the triggering event and then
got stack information before trying to shutdown the app. At this point,
our app is leaking like a sieve because the GC is blocked, but the app is
still running "apparently" normally (though obviously leaking).

You are confusing the GC with the "finalizer", the GC is run on the thread
that made an object allocation, the "finalizer" thread is a separate
dedicated thread that runs the objects finalize methods if any.


The managed threads info is here:

ThreadCount: 11
UnstartedThread: 0
BackgroundThread: 4
PendingThread: 0
DeadThread: 5
PreEmptive GC Alloc Lock
ID ThreadOBJ State GC Context Domain
Count APT Exception
0 0xe34 0x0014a760 0x6020 Enabled 0x00000000:0x00000000 0x0015c240
0 STA
1 0xdd8 0x00153228 0xb220 Enabled 0x00000000:0x00000000 0x0015c240
0 MTA (Finalizer)
21 0x658 0x082666f8 0x2001220 Enabled 0x00000000:0x00000000 0x0015c240
0 Ukn
XXX 0 0x081868b0 0x1820 Enabled 0x00000000:0x00000000
0x0015c240 0 Ukn
29 0xd10 0x08cde780 0x2001220 Enabled 0x00000000:0x00000000 0x0015c240
0 Ukn
5 0xfdc 0x081f0ba8 0x2001220 Enabled 0x00000000:0x00000000 0x0015c240
0 Ukn
30 0xd40 0x07436a00 0x2001020 Enabled 0x00000000:0x00000000 0x0015c240
0 Ukn
XXX 0 0x0978f5d0 0x1820 Enabled 0x00000000:0x00000000
0x0015c240 0 Ukn
XXX 0 0x09d461b8 0xb820 Enabled 0x00000000:0x00000000
0x0015c240 0 Ukn
XXX 0 0x09d26338 0x1820 Enabled 0x00000000:0x00000000
0x0015c240 0 Ukn
XXX 0 0x09d26d98 0x1820 Enabled 0x00000000:0x00000000
0x0015c240 0 Ukn

As you can see, Thread 1 is the GC in an MTA and Thread 0 is the main app
thread in an STA.

Thread 1 is the *finalizer* thread running in an MTA.
The unmanaged callstack for the GC thread is here:

1 Id: e38.dd8 Suspend: 1 Teb: 7ffdd000 Unfrozen
ChildEBP RetAddr Args to Child
02f3f66c 7c90e9c0 7c8025cb 000004c8 00000000 ntdll!KiFastSystemCallRet
02f3f670 7c8025cb 000004c8 00000000 00000000
ntdll!ZwWaitForSingleObject+0xc
02f3f6d4 7c802532 000004c8 ffffffff 00000000
KERNEL32!WaitForSingleObjectEx+0xa8
02f3f6e8 7752abbd 000004c8 ffffffff 001ba128
KERNEL32!WaitForSingleObject+0x12
02f3f704 77601e51 001ba128 00213a60 00000000 ole32!GetToSTA+0x6f
02f3f724 7760109a 02f3f7ec 02f3f8fc 001ba6e0
ole32!CRpcChannelBuffer::SwitchAptAndDispatchCall+0xf6
02f3f804 7751047c 001ba6e0 02f3f8fc 02f3f8ec
ole32!CRpcChannelBuffer::SendReceive2+0xb9
02f3f870 775265b5 001ba6e0 02f3f8fc 02f3f8ec
ole32!CAptRpcChnl::SendReceive+0xab
02f3f8c4 77ef4db5 00000001 02f3f8fc 02f3f8ec
ole32!CCtxComChnl::SendReceive+0x91
02f3f8e0 77ef4ead 09907014 02f3f928 0600015b
RPCRT4!NdrProxySendReceive+0x43
02f3fcbc 77ef4e42 774e6218 774e95d6 02f3fcf4 RPCRT4!NdrClientCall2+0x1fa
02f3fcdc 77e8a453 0000000c 00000008 02f3fd74
RPCRT4!ObjectStublessClient+0x8b
02f3fcec 77526191 09907014 02f3fd28 00000000 RPCRT4!ObjectStubless+0xf
02f3fd74 7758a7c6 0016be08 79208811 02f3fe0c
ole32!CObjectContext::InternalContextCallback+0x122
02f3fdc4 79206f4e 0016be18 79208811 02f3fe0c
ole32!CObjectContext::ContextCallback+0x85
02f3fe70 79208031 79208848 0376b118 00000000
mscorwks!CtxEntry::EnterContext+0xb7
02f3fe98 792070c7 00000000 793eefb8 00000000
mscorwks!ComPlusApartmentCleanupGroup::CleanUpWrappers+0x63
02f3fed0 79216d5d 7c80a017 00000000 792167fb
mscorwks!ComPlusWrapperCleanupList::CleanUpWrappers+0x69
02f3fedc 792167fb 791b9974 00000000 791d0bab
mscorwks!SyncBlockCache::CleanupSyncBlocks+0x85
02f3fee0 791b9974 00000000 791d0bab 001533f0
mscorwks!Thread::DoExtraWorkForFinalizer+0x23

As you can see in the ole32!GetToSTA, the GC is trying to get to the STA
thread to dispose of some COM object. Basically, the thread is just stuck
there and not doing anything. I would think that would mean that the STA
thread (thread 0) is hung as well, but in this case, Thread 0 is not hung.

The finalizer thread is blocked waiting for a cross-thread call to return.
The managed callstack for Thread0 at the same time is this:

Thread 0
ESP EIP
0x0012f374 0x7c90eb94 [FRAME: InlinedCallFrame]
0x0012f35c 0x7b82e116 [DEFAULT] [hasThis] Boolean
System.Windows.Forms.Application/ComponentManager.System.Windows.Forms.UnsafeNativeMethods+IMsoComponentManager.FPushMessageLoop(I4,I4,I4)
0x0012f3f4 0x7b82daca [DEFAULT] [hasThis] Void
System.Windows.Forms.Application/ThreadContext.RunMessageLoopInner(I4,Class
System.Windows.Forms.ApplicationContext)
0x0012f430 0x7b82d7e5 [DEFAULT] [hasThis] Void
System.Windows.Forms.Application/ThreadContext.RunMessageLoop(I4,Class
System.Windows.Forms.ApplicationContext)
0x0012f45c 0x7b87cba1 [DEFAULT] Void
System.Windows.Forms.Application.Run(Class
System.Windows.Forms.ApplicationContext)
0x0012f464 0x03b24622 [DEFAULT] [hasThis] Void MyApp.UI.Workbench.Run()
at [+0x32a] [+0x18b]
0x0012f4b4 0x030df137 [DEFAULT] Void
MyApp.Platform.ApplicationController.StartApplication(String)
at [+0x58f] [+0x1bc]
0x0012f5ac 0x030dc953 [DEFAULT] [hasThis] Void MyApp.MyApp.StartApp()
at [+0x40b] [+0x1f5]
E:\Ascential\Clearcase\davisp_m81\MyApp\src\MyApp.cs:16707566
0x0012f638 0x030d2864 [DEFAULT] [hasThis] Void MyApp.MyApp.Run(SZArray
String)
at [+0x1f4] [+0xe8]
E:\Ascential\Clearcase\davisp_m81\MyApp\src\MyApp.cs:617
0x0012f68c 0x030d016c [DEFAULT] Void MyApp.MyApp.Main(SZArray String)
at [+0xc4] [+0x6b]
E:\Ascential\Clearcase\davisp_m81\MyApp\src\MyApp.cs:273
0x0012f8b0 0x791dc474 [FRAME: GCFrame]
0x0012f9b0 0x791dc474 [FRAME: GCFrame]
0x0012fa94 0x791dc474 [FRAME: GCFrame]

So the STA thread is pumping the message loop. So why can't the GC get to
the STA thread?

The thread is not pumping, he's currently running at 0x7c90eb94, he's
probably processing a message ...
Thread 21 is the JuggerNET GC thread and it has this unmanaged callstack:

21 Id: e38.658 Suspend: 1 Teb: 7ffa5000 Unfrozen
ChildEBP RetAddr Args to Child
0875f92c 7c90e9ab 7c8094e2 00000001 0875f958 ntdll!KiFastSystemCallRet
0875f930 7c8094e2 00000001 0875f958 00000001
ntdll!ZwWaitForMultipleObjects+0xc
0875f9cc 7929b344 00000001 793e2df8 00000000
KERNEL32!WaitForMultipleObjectsEx+0x12c
0875f9fc 7929b8a5 00000001 793e2df8 00000000
mscorwks!Thread::DoAppropriateWaitWorker+0xc1
0875fa50 79265e5c 00000001 793e2df8 00000000
mscorwks!Thread::DoAppropriateWait+0x46
0875fa78 79218d41 ffffffff 035b2e17 0875fa8c
mscorwks!GCHeap::FinalizerThreadWait+0x76
0875fab4 791dc474 0875fbcc 791dce6f 0875fb08
mscorwks!GCInterface::RunFinalizers+0x7
0875faec 791d8b62 00000000 00000000 0875fbcc mscorwks!CallDescrWorker+0x30
0875fafc 791dcd61 791dcd71 79bca8cb 79b7c000
mscorwks!MetaSig::SizeOfActualFixedArgStack+0x14
0875fbcc 791ddb14 00bca8cb 79b7c000 0875fbf8
mscorwks!MethodDesc::CallDescr+0x79
0875fc88 791ddb82 79bca8cb 79b7c000 79b93e78
mscorwks!MethodDesc::CallDescr+0x4f
0875fcb0 792ea4af 0875fcf4 082666f8 791b33f8
mscorwks!MethodDesc::Call+0x97
0875fcfc 792ea57e 0875fd14 0807ad40 792ea4bc
mscorwks!ThreadNative::KickOffThread_Worker+0x9d
0875fda0 791c94b4 0807ad40 804fd2b8 00000100
mscorwks!ThreadNative::KickOffThread+0xc2
0875ffb4 7c80b683 08059fe8 00000000 082668c0
mscorwks!Thread::intermediateThreadProc+0x44
0875ffec 00000000 791c9473 08059fe8 00000000 KERNEL32!BaseThreadStart+0x37

Could this be blocking the regular GC thread?
This thread is waiting for the finalizer thread to return, this thread has a
pending WaitForPeningFinalizers.

Summary:
Thread 0 is busy with???
Thread 1 is waiting for an outstanding STA call to return.
Thread 21 is waiting in a WaitForPeningFinalizers call.

It looks like thread 0 is executing code, more he's actually processing a
message from it's message queue, but there is nothing wrong with this.

Willy.
 
F

Fredo

Willy,

Thanks for your diagnosis. I'm pretty sure I've found the source of the
problem, but I'm not entirely sure how to fix it. I'll use your corrected
terminology...

The finalizer thread seems to be calling either 4 methods or the same method
4 times in a row, periodically. The methods all get called together. These 4
methods have to be invoked on the STA, so it's being done via an Invoke of
some sort which means it's passed in the Windows message queue.

We can reproduce the problem by using our own ContextMenu class. Underneath,
the ContextMenu uses our PopupMenu class. For certain uses of the PopupMenu,
we internally create a message loop and message pump. (For the record, this
code was produced by someone in India about 3 or 4 years ago and I have a
LOT of issues with the code besides this).

The message pump is in two methods. The main message loop is here:

while (!exitMessageLoop_)
{
if (WindowsAPI.WaitMessage())
{
while ((!exitMessageLoop_ &&
(WindowsAPI.PeekMessage(ref msgstruct, 0, 0, 0,
(int)PeekMessageFlags.PM_NOREMOVE)))
{
ProcessMessage(msgstruct);
}
}
}


ProcessMessage then deals with some messages and near the end does this:

if (WindowsAPI.GetMessage(ref msgstruct, 0, 0, 0))
{
WindowsAPI.TranslateMessage(ref msgstruct);
WindowsAPI.DispatchMessage(ref msgstruct);
}

I should mention, one other oddity about this class is that it's derived
directly from NativeWindow, not from Control. I'm not sure if that makes a
difference, but it might, since it and its menu items will never go to the
parking window.

The problem seems to occur if the popup menu is displayed at the same time
that the finalizer thread makes its 4 calls. The 4 messages appear to be
pumped properly through the PopupMenu's message pump, based on some
Debug.WriteLines I put into the pump, but somehow one or more of them must
not be getting through. I'm not sure why. But if the popup is displayed just
as the 4 messages come through, the finalizer hangs and the app starts
leaking.

I have no idea how to fix this short of re-architecting the popup menu which
would be virtually impossible at this point.

Thanks.
 
W

Willy Denoyette [MVP]

Fredo said:
Willy,

Thanks for your diagnosis. I'm pretty sure I've found the source of the
problem, but I'm not entirely sure how to fix it. I'll use your corrected
terminology...

The finalizer thread seems to be calling either 4 methods or the same
method 4 times in a row, periodically. The methods all get called
together. These 4 methods have to be invoked on the STA, so it's being
done via an Invoke of some sort which means it's passed in the Windows
message queue.

We can reproduce the problem by using our own ContextMenu class.
Underneath, the ContextMenu uses our PopupMenu class. For certain uses of
the PopupMenu, we internally create a message loop and message pump. (For
the record, this code was produced by someone in India about 3 or 4 years
ago and I have a LOT of issues with the code besides this).

The message pump is in two methods. The main message loop is here:

while (!exitMessageLoop_)
{
if (WindowsAPI.WaitMessage())
{
while ((!exitMessageLoop_ &&
(WindowsAPI.PeekMessage(ref msgstruct, 0, 0, 0,

(int)PeekMessageFlags.PM_NOREMOVE)))
{
ProcessMessage(msgstruct);
}
}
}


ProcessMessage then deals with some messages and near the end does this:

if (WindowsAPI.GetMessage(ref msgstruct, 0, 0, 0))
{
WindowsAPI.TranslateMessage(ref msgstruct);
WindowsAPI.DispatchMessage(ref msgstruct);
}

I should mention, one other oddity about this class is that it's derived
directly from NativeWindow, not from Control. I'm not sure if that makes a
difference, but it might, since it and its menu items will never go to the
parking window.

The problem seems to occur if the popup menu is displayed at the same time
that the finalizer thread makes its 4 calls. The 4 messages appear to be
pumped properly through the PopupMenu's message pump, based on some
Debug.WriteLines I put into the pump, but somehow one or more of them must
not be getting through. I'm not sure why. But if the popup is displayed
just as the 4 messages come through, the finalizer hangs and the app
starts leaking.

I have no idea how to fix this short of re-architecting the popup menu
which would be virtually impossible at this point.

Thanks.


The finalizer thread only needs a message pump to run the finalizers of the
RCW's, other finalize methods run directly on the finalizer thread. In your
case, where you have an AX control running in an STA on the UI thread
(thread 0), the finalizer thread cannot run the RCW(s) (managed wrapper
around the COM AX control) finalize method(s), so he needs to marshal the
call to the UI thread using the UI threads message pump. If you fail to
pump, or if you block in the finalize method, the finalizer thread will
block also, and that's what happening in your case (see your Original Post).
Your previous post however, did not illustrate such behavior, the UI thread
was actively executing in a message pump. The fact that the finalizer thread
is calling the RCW's finalize method is an indication that you aren't
explicitly disposing of the RCW 's when the application closes down. So,
what you can/should do to prevent finalizer lock-ups at process shutdown
time, is to explicitly dispose the RCW of the AX control in your OnClosing
handler, this should solve the finalizer issue, but not the (now latent) bug
of a failing message pump.

Willy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top