需要帮助解密C#堆栈跟踪

时间:2009-02-17 23:43:32

标签: c# stack-trace

我有一个锁定GUI线程的应用程序,我使用WinDbg和“!clrstack”命令来获取此堆栈跟踪,但我无法弄清楚问题所在。所有这些方法看起来都像框架方法,没有一个是我的。任何帮助将非常感激。我为长队道歉

OS Thread Id: 0x724 (0)
ESP       EIP     
0012ec88 7c90e4f4 [HelperMethodFrame_1OBJ: 0012ec88] System.Threading.WaitHandle.WaitOneNative(Microsoft.Win32.SafeHandles.SafeWaitHandle, UInt32, Boolean, Boolean)
0012ed34 792b687f System.Threading.WaitHandle.WaitOne(Int64, Boolean)
0012ed50 792b6835 System.Threading.WaitHandle.WaitOne(Int32, Boolean)
0012ed64 7b6f192f System.Windows.Forms.Control.WaitForWaitHandle(System.Threading.WaitHandle)
0012ed78 7ba2d0bb System.Windows.Forms.Control.MarshaledInvoke(System.Windows.Forms.Control, System.Delegate, System.Object[], Boolean)
0012ee18 7b6f328c System.Windows.Forms.Control.Invoke(System.Delegate, System.Object[])
0012ee4c 7b920717 System.Windows.Forms.WindowsFormsSynchronizationContext.Send(System.Threading.SendOrPostCallback, System.Object)
0012ee64 7a924102 Microsoft.Win32.SystemEvents+SystemEventInvokeInfo.Invoke(Boolean, System.Object[])
0012ee98 7a922833 Microsoft.Win32.SystemEvents.RaiseEvent(Boolean, System.Object, System.Object[])
0012eee4 7a923d2f Microsoft.Win32.SystemEvents.OnUserPreferenceChanged(Int32, IntPtr, IntPtr)
0012ef04 7aa8f184 Microsoft.Win32.SystemEvents.WindowProc(IntPtr, Int32, IntPtr, IntPtr)
0012ef08 003620a4 [InlinedCallFrame: 0012ef08] 
0012f0cc 7b1d8cce System.Windows.Forms.Application+ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32, Int32, Int32)
0012f168 7b1d8937 System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext)
0012f1bc 7b1d8781 System.Windows.Forms.Application+ThreadContext.RunMessageLoop(Int32, System.Windows.Forms.ApplicationContext)
0012f1ec 7b195911 System.Windows.Forms.Application.Run(System.Windows.Forms.Form)
0012f200 00eb0ebb WinForms1.Program.Main()
0012f69c 79e71b4c [GCFrame: 0012f69c] 

4 个答案:

答案 0 :(得分:8)

看起来这段代码不是问题的真正原因。看看其中一个页面是否有帮助:

更新:修正了第一页的网址。

答案 1 :(得分:3)

另一个答案来自Aaron Lerch。我真的很喜欢“在其他人的代码上过滤断点”部分。我想这会让我节省几天。

http://www.aaronlerch.com/blog/2008/12/15/debugging-ui/

答案 2 :(得分:1)

我有类似的问题,并在我们的代码中找到了罪魁祸首。

使用的技术: 0.确保在Spy ++中只有两个带有控件的非托管线程(WinForms和GDI +):

public static class ThreadingHelper_NativeMethods
{
   [DllImport("user32.dll")]
   public static extern bool IsGUIThread(bool bConvert);
}

在init上从UI线程调用它:

// This code forces initialization of .NET BroadcastEventWindow to the UI thread.
// http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/fb267827-1765-4bd9-ae2f-0abbd5a2ae22
if (ThreadingHelper_NativeMethods.IsGUIThread(false))
{
    Microsoft.Win32.SystemEvents.InvokeOnEventsThread(new MethodInvoker(delegate()
    {
    int x = 0;
    }));
}
  1. 在单例类中记住Ui Thread的托管ID。

  2. 搜索我们代码中定义的所有UserControl。在每个控件的构造函数中,在调用InitializeComponent()之前,我放置了检查当前线程id与主线程id的代码。如果它们不相等,则Assert(false)。

  3. 订阅SystemEvents.UserPreferencesChanging。处理程序中的Debug.Assert(false):这发生在SystemEvents.UserPreferencesChanged之前,因此调试器有望在这里暂停。

  4. 检查调试器中SystemEvents的订户列表。在_handles词典列表中查找订阅者。打开每个回调的SynchronizationContext应该揭示问题:与在非UI线程上创建的控件相同的线程ID。 SystemEvents将在该线程上执行事件处理程序,对UI线程进行死锁。

答案 3 :(得分:0)

this答案中的CheckSystemEventsHandlersForFreeze()函数可以帮助您找到导致GUI线程被锁定的根本原因。

相关问题