记一次 .NET 某企业OA后端服务 卡死分析

网站建设4年前发布
32 0 0

前段时间有位朋友微信找到我,说他生产机器上的 Console 服务看起来像是卡死了,也不生成日志,对方也收不到我的httpclient请求,不知道程序出现什么情况了,特来寻求帮助。,哈哈,一般来说卡死的情况在窗体程序(WinForm,WPF) 上特别多,在 Console,WebApi 中相对较少,既然找到我,那就上 WinDbg 分析吧。,程序之所以能跑的梭梭响,全靠线程帮忙,如果玩不转可能就是线程上出了点什么问题,接下来使用 !t 展示下线程列表。,一般来说卦中的 Lock Count​ 列表示当前线程所持有的托管锁个数,现在显示的 -00001​ 应该是命令不起效果了。。。不过没关系,我们还可以通过 !syncblk​ 来看下 lock 的情况,毕竟 95% 的锁场景都会用到它。,从卦中的 MonitorHeld=27​ 来看,表示这个 SyncTextWriter 对象当前有 13 个线程在等待,有 1 个线程在持有,那这个线程为什么没有退出呢?接下来可以切到 53 号线程上,查看下它的线程栈。,仔细观察线程栈会很惊讶的发现,居然还能卡在 System.Console.WriteLine​ 方法上,挺奇怪的,为了探究原因,我们使用 k 命令看下非托管栈。,从上面的 syscall​ 系统调用关键词看,代码是将用户态的 ntdll!NtWriteFile​ 切到入了内核态的 nt!NtWriteFile 方法,那进入了内核态为什么没有返回呢?这又是一个值得思索的问题。,其实 ntdll!NtWriteFile 这个 win32 api 方法的第一个参数是一个 handle 的文件句柄,签名如下。,可能 handle 在内核中被别人占用了,可以用 !handle​ 查看下 rcx 寄存器。,哈哈,其实也看不出什么,也没法进入内核态,所以下一步只能到网上搜搜看,其实有经验的朋友肯定猜出来了,应该是控制台启用了 快捷编辑窗口 ,截图如下:,20230306010108a6128c8201246351b923644780e0f45688a27a167,快捷编辑窗口​ 简而言之就是用户可以在控制台上独占这个窗口,编辑一些内容, 可一旦被用户独占,那程序侧就没法输出内容到 控制台窗口​ 上了,只能在 内核态 傻傻等等,这应该就是形成原因,画个图大概就像下面这样。,202303060101080351f5341b7a0aba122411f6a121b452e1c4ae330,将信息告诉朋友后,朋友说他用的是 Windows 服务部署,但不管是什么模式部署,注释掉 Console.WriteLine 肯定没错。,这次卡死的事故,主要还是开发人员大量的使用 Console.WriteLine 来输出日志,在某个时刻输出端窗口因为各种原因被他人独占,导致程序侧无法输出内容到窗口而一直被迫等待,之后朋友将日志输出切换到文件模式,问题得以解决。,其实这个问题很多新手朋友都会犯,特此记录下来。

© 版权声明

相关文章