簡體   English   中英

需要幫助解密C#堆棧跟蹤

[英]Need help deciphering a 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] 

看起來這段代碼不是問題的真正原因。 看看其中一個頁面是否有幫助:

更新:修復了第一頁的網址。

另一個答案來自這個Aaron Lerch。 我真的很喜歡“在其他人的代碼上過濾斷點”部分。 我想這會節省我幾天的時間。

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

我有類似的問題,並在我們的代碼中發現了罪魁禍首。

使用的技術: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的代碼。 如果它們不相等,則斷言(假)。

  3. 訂閱SystemEvents.UserPreferencesChanging。 處理程序中的Debug.Assert(false):這發生在SystemEvents.UserPreferencesChanged之前,因此調試器有望在這里暫停。

  4. 檢查調試器中SystemEvents的訂戶列表。 在_handles詞典列表中查找訂閱者。 打開每個回調的SynchronizationContext應該揭示問題:與在非UI線程上創建的控件相同的線程ID。 SystemEvents將在該線程上執行事件處理程序,對UI線程進行死鎖。

答案中的函數CheckSystemEventsHandlersForFreeze()可以幫助您找到GUI線程被鎖定的根本原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM