最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

監(jiān)控系統(tǒng)的死鎖分析

2023-04-07 12:47 作者:程序員-王堅(jiān)  | 我要投稿

程序?yàn)槭裁磿?huì)卡死

因?yàn)槭谴绑w程序,所以看主線程的線程棧就好了,如果卡在?用戶態(tài)?那這個(gè)問(wèn)題相對(duì)容易解決,如果卡在?內(nèi)核態(tài)?這個(gè)問(wèn)題就比較復(fù)雜了,需要開(kāi)啟 WinDbg 的本機(jī)內(nèi)核調(diào)試或者雙機(jī)調(diào)試才能找到最終的問(wèn)題。

既然已經(jīng)說(shuō)了是入門(mén)級(jí),那肯定是卡在?用戶態(tài)?層面啦,我們用?!clrstack?命令觀察下主線程的線程棧即可,輸出如下:

0:000:x86> !clrstack OS Thread Id: 0x31d8 (0) Child SP ? ? ? IP Call Site00f9ec28 00e9e108 [GCFrame: 00f9ec28] 00f9ed08 00e9e108 [GCFrame: 00f9ed08] 00f9ed24 00e9e108 [HelperMethodFrame_1OBJ: 00f9ed24] System.Threading.Monitor.ReliableEnter(System.Object, Boolean ByRef)00f9eda0 70c08468 System.Threading.Monitor.Enter(System.Object, Boolean ByRef) [f:\dd\ndp\clr\src\BCL\system\threading\monitor.cs @ 62]00f9edb0 0ce916c7 xxxx.GetAlarmCount(xxx)00f9ee28 0961f41f xxx.xxx()00f9ef04 0961d60a xxxx.xxx(System.Object, System.EventArgs)00f9ef50 6de03dc9 System.Windows.Forms.Timer.OnTick(System.EventArgs)00f9ef58 6de053d9 System.Windows.Forms.Timer+TimerNativeWindow.WndProc(System.Windows.Forms.Message ByRef)00f9ef64 6ddd38d0 System.Windows.Forms.NativeWindow.Callback(IntPtr, Int32, IntPtr, IntPtr)00f9f1b0 0130d5d4 [InlinedCallFrame: 00f9f1b0] 00f9f1ac 6de375bd DomainBoundILStubClass.IL_STUB_PInvoke(MSG ByRef)00f9f1b0 6dde44e3 [InlinedCallFrame: 00f9f1b0] System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG ByRef)00f9f1e4 6dde44e3 System.Windows.Forms.Application+ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr, Int32, Int32)00f9f1e8 6dde40d1 [InlinedCallFrame: 00f9f1e8] 00f9f270 6dde40d1 System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext)00f9f2c0 6dde3f23 System.Windows.Forms.Application+ThreadContext.RunMessageLoop(Int32, System.Windows.Forms.ApplicationContext)00f9f2ec 6ddbc83d System.Windows.Forms.Application.Run(System.Windows.Forms.Form)00f9f300 01350a6e CleanControl.Program.Main(System.String[])00f9f4ec 71d00556 [GCFrame: 00f9f4ec] ...

從卦中看,主線程卡在?Monitor.Enter?處,也就表明當(dāng)前線程在?GetAlarmCount()?方法的一個(gè) lock 處等待。

2. 誰(shuí)在持有鎖

要想找到誰(shuí)在持有鎖,需要理解?lock?的底層機(jī)制,它是建立在?AutoResetEvent + ObjectHeader?基礎(chǔ)之上的一種鎖玩法,在 CLR 層面使用?SyncBlk?的 class 來(lái)承載的,參考如下代碼:

class SyncBlock{ // ObjHeader creates our Mutex and Event friend class ObjHeader; friend class SyncBlockCache; friend struct ThreadQueue;#ifdef DACCESS_COMPILE friend class ClrDataAccess;#endif friend class CheckAsmOffsets;protected: AwareLock ?m_Monitor; ? ? ? ? ? ? ? ? ? ?// the actual monitor SLink ? ? ? m_Link; DWORD m_dwHashCode; WCHAR m_BSTRTrailByte; }

要想觀察這些?SyncBlk?信息,可以用 WinDbg 提供的快捷命令?!syncblk?來(lái)觀察。

0:000:x86> !syncblk Index ? ? ? ? SyncBlock MonitorHeld Recursion Owning Thread Info ? ? ? ? ?SyncBlock Owner ?180 0b86e8e8 ? ? ? ? ? ?3 ? ? ? ? 1 01452a08 3728 ?24 ? 039da140 System.Object ----------------------------- Total ? ? ? ? ? 339CCW ? ? ? ? ? ? 5RCW ? ? ? ? ? ? 2ComClassFactory 0Free ? ? ? ? ? ?4

從卦中看,當(dāng)前持有 lock 的線程是?24?號(hào),那這個(gè)線程為什么遲遲不退出鎖呢? 這就需要到這個(gè)線程棧上找原因了, 使用命令?~24s; !clrstack?即可。

0:004:x86> ~24s ntdll_779a0000!NtWaitForMultipleObjects+0xc:77a11b2c c21400 ? ? ? ? ?ret ? ? 14h0:024:x86> !clrstack OS Thread Id: 0x3728 (24) Child SP ? ? ? IP Call Site0e99e504 0000002b [HelperMethodFrame_1OBJ: 0e99e504] System.Threading.WaitHandle.WaitOneNative(System.Runtime.InteropServices.SafeHandle, UInt32, Boolean, Boolean)0e99e5e8 70bdd952 System.Threading.WaitHandle.InternalWaitOne(System.Runtime.InteropServices.SafeHandle, Int64, Boolean, Boolean) [f:\dd\ndp\clr\src\BCL\system\threading\waithandle.cs @ 243]0e99e600 70bdd919 System.Threading.WaitHandle.WaitOne(Int32, Boolean) [f:\dd\ndp\clr\src\BCL\system\threading\waithandle.cs @ 194]0e99e614 6e4aa4a8 System.Windows.Forms.Control.WaitForWaitHandle(System.Threading.WaitHandle)0e99e654 6e8585af System.Windows.Forms.Control.MarshaledInvoke(System.Windows.Forms.Control, System.Delegate, System.Object[], Boolean)0e99e658 6e4acc4f [InlinedCallFrame: 0e99e658] 0e99e6e0 6e4acc4f System.Windows.Forms.Control.Invoke(System.Delegate, System.Object[]) ...0e99e83c 0f46512c xxx.AddAlarmQueue(xxx) ...0e99ea84 0d3f2783 xxx.Func()0e99ead8 70be2e01 System.Threading.ThreadHelper.ThreadStart_Context(System.Object) [f:\dd\ndp\clr\src\BCL\system\threading\thread.cs @ 74] ...

從卦中看,其中的?MarshaledInvoke?方法很刺眼,它表示工作線程通過(guò) Invoke 向主線程的控件推送數(shù)據(jù),因?yàn)橹骶€程遲遲沒(méi)有響應(yīng)它,導(dǎo)致它一直在等待,而恰恰它又持有了 lock 鎖,不趕巧主線程因?yàn)楂@取lock在遲遲等待又無(wú)法響應(yīng)工作線程的 MarshaledInvoke 請(qǐng)求,導(dǎo)致一種死鎖狀態(tài),如果要畫(huà)個(gè)圖大概是這樣的。

3. 如何化解

尋得化解之法,需要看下程序中是怎么持有 lock 鎖的,仔細(xì)觀察代碼之后,終于找到了 lock 代碼處,截圖如下:

對(duì)代碼敏感得朋友相信一眼就能看出,這 lock 的粒度真tmd的大,只要 lock 中有一處調(diào)用了 Invoke,如果不湊巧主線程剛好在等待 lock ,那就死鎖了,正如本篇中的 死鎖。


監(jiān)控系統(tǒng)的死鎖分析的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
岳阳县| 祥云县| 淮阳县| 赤壁市| 汝阳县| 灌南县| 子长县| 剑河县| 大荔县| 新营市| 蓬安县| 全州县| 嘉义县| 萨嘎县| 镇赉县| 宝应县| 牡丹江市| 墨玉县| 古交市| 郯城县| 芦山县| 海兴县| 高雄县| 双鸭山市| 松江区| 中超| 江北区| 黄骅市| 阳城县| 蒙阴县| 双鸭山市| 江华| 无锡市| 即墨市| 霍州市| 海城市| 崇阳县| 宜黄县| 连平县| 宁夏| 玉树县|