机票燃油附加费年内第二次下调:今起单程最低降至30元
3月底开始,中国民航正式执行2023年夏秋航季航班计划,国际航班票价
上周看了一位训练营朋友的dump,据朋友说他的程序卡死了,看完之后发现是一例经典的死锁问题,蛮有意思,这个案例算是学习.NET高级调试入门级的案例,这里和大家分享一下。
二:WinDbg 分析1. 程序为什么会卡死因为是窗体程序,所以看主线程的线程栈就好了,如果卡在用户态那这个问题相对容易解决,如果卡在内核态这个问题就比较复杂了,需要开启 WinDbg 的本机内核调试或者双机调试才能找到最终的问题。
(相关资料图)
既然已经说了是入门级,那肯定是卡在用户态层面啦,我们用!clrstack命令观察下主线程的线程栈即可,输出如下:
0:000:x86> !clrstackOS 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处,也就表明当前线程在GetAlarmCount()方法的一个 lock 处等待。
2. 谁在持有锁要想找到谁在持有锁,需要理解lock的底层机制,它是建立在AutoResetEvent + ObjectHeader基础之上的一种锁玩法,在 CLR 层面使用SyncBlk的 class 来承载的,参考如下代码:
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来观察。
0:000:x86> !syncblkIndex SyncBlock MonitorHeld Recursion Owning Thread Info SyncBlock Owner 180 0b86e8e8 3 1 01452a08 3728 24 039da140 System.Object-----------------------------Total 339CCW 5RCW 2ComClassFactory 0Free 4
从卦中看,当前持有 lock 的线程是24号,那这个线程为什么迟迟不退出锁呢?这就需要到这个线程栈上找原因了, 使用命令~24s; !clrstack即可。
0:004:x86> ~24sntdll_779a0000!NtWaitForMultipleObjects+0xc:77a11b2c c21400 ret 14h0:024:x86> !clrstackOS 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方法很刺眼,它表示工作线程通过 Invoke 向主线程的控件推送数据,因为主线程迟迟没有响应它,导致它一直在等待,而恰恰它又持有了 lock 锁,不赶巧主线程因为获取lock在迟迟等待又无法响应工作线程的 MarshaledInvoke 请求,导致一种死锁状态,如果要画个图大概是这样的。
3. 如何化解寻得化解之法,需要看下程序中是怎么持有 lock 锁的,仔细观察代码之后,终于找到了 lock 代码处,截图如下:
对代码敏感得朋友相信一眼就能看出,这 lock 的粒度真tmd的大,只要 lock 中有一处调用了 Invoke,如果不凑巧主线程刚好在等待 lock ,那就死锁了,正如本篇中的 死锁。
三:总结这次卡死事故,本质上来说是程序员对锁的使用没有一个好的习惯,没有遵循锁的尽早释放原则。
其实这一块关系型数据库做的特别好,锁的粒度分的很细,诸如:行锁,RID锁,Key锁,页锁,表锁,在必要的时候还会涉及到锁的升级,将性能,锁开销,一致性 做到了极致,非常值得我们研究和学习。
关键词:
3月底开始,中国民航正式执行2023年夏秋航季航班计划,国际航班票价
1、liang(第四声):数量,总量,量变,肚量,量子,思量,打量,量化,量力,量产,量刑liang(第二声):衡量,度
你需要的东西精灵耳朵图案,打印出来双面胶带铅笔工艺泡沫剪刀热胶枪蜡笔或喷漆有精灵的电影的流行使得精灵服装在聚会和其他有趣的场合很受欢
<p>高速光耦国产,成就制造新辉煌!< p><p>随着科技的不断进步,光电技术在各个领域中的应用越来越广泛。而作为光电技术中的重要组成部分,光
知名评论员A-史密斯今日在NBACountdown节目中谈到了安东尼-戴维斯。A-史密斯说道:“我爱AD,我喜欢他的比赛,但他有一个问题,就是不能总在要劲的
由美国硅谷银行倒闭开始,欧美银行业出现一系列动荡事件,银行股大幅波动,市场恐慌情绪发酵。虽然直接原因是银行自身资产负债表期限错配,以
青岛海底世界青岛海底世界是国家4A级旅游风景区和全国科普教育基地,景区位于青岛汇泉湾畔,毗邻鲁迅公园和第一海水浴场,是栈桥和八大关之间
全国两会精神看落实丨细微之处察民情幸福社区暖民心---2023年全国两会闭幕后,各地真抓实干持续保障和改善民生,落细一张张“民生清单”,兑现
4月4日海能技术跌7 75%,汇添富健康生活一年持有混合A基金重仓该股,汇添富,重仓股,公募基金,基金产品,qdii,海能技术,健康生活,基金资产净值
输油管道板块股票一览(2023 4 4),输油管道板块股票一览(2023 4 4)南方财富网为您整理的2023年输油管道概念股,供大家参考。金洲管道002443
相信有许多看你怎么秀同学还不清楚看你怎么秀启强租房攻略详解,现在让第一资讯网小编收集编写的《看你怎么秀启强租房攻略详解》,有这些疑问
近日,国家“十四五”重点研发计划——工业软件专项“产品回收拆解再利用全流程管控平台研发与示范”项目启动会暨实施方案论证会
格隆汇4月4日丨隆华新材(301149 SZ)公布,公司于2023年4月3日取得高青县行政审批服务局出具的项目备案。项目
1、具体职务不清楚。2、这个人现在好像不在了。本文就为大家分享到这里,希望小伙伴们会喜欢。
1、先了解自己的脚型:因扁平足会有关节较松、较不稳定的情形,须选择鞋护跟较硬,稳定性较佳的鞋子;高弓足则缺乏正常吸震缓冲的能力,须选择
Copyright 2015-2022 世界双创网 版权所有 备案号:琼ICP备2022009675号-1 联系邮箱:435 227 67@qq.com
致敬老将!热爱可抵岁月漫长
<script src="http: tv people com cn img player v js">< script><script>showPlayer({id:" pvservice xml 202
微视频|字里藏情迎元宵
<script src="http: tv people com cn img player v js">< script><script>showPlayer({id:" pvservice xml 202
【每日一习话】世界上最大的幸福莫过于为人民幸福而奋斗
<script src="http: tv people com cn img player v js">< script><script>showPlayer({id:" pvservice xml 202