WinDbg的 - 的TraceListener和饱和线程池 [英] WinDbg -- TraceListener and Saturated ThreadPool

查看:196
本文介绍了WinDbg的 - 的TraceListener和饱和线程池的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个多线程的.NET Windows服务是挂起间歇性 - 24/7操作可能每两周一次。当挂起时线程池是完全饱和,因为调用我们自定义的TraceListener开始阻止出于某种原因。有没有阻止根据WinDbg中的违规code任何锁,也没有什么,但他们肯定阻塞的地方。有没有在堆栈上的任何异常无论是。有一个Thread.sleep代码(1)有时会在BufferedStream.Write code受到较大冲击,但我的问题是,什么是ReOpenMetaDataWithMemory,CreateApplicationContext和DllCanUnloadNow是什么意思?

几乎所有的2000年挂了工作线程(!不正常操作)的线程池也有类似以下内容的堆栈:

  0:027> !dumpstack
操作系统线程ID:0x1638(27)
儿童-SP RetAddr呼叫网站
000000001d34df58 0000000077d705d6 NTDLL!ZwDelayExecution +是0xA
000000001d34df60 000006427f88901d KERNEL32!SleepEx + 0x96
000000001d34e000 000006427f454379 mscorwks!DllCanUnloadNowInternal + 0xf53d
000000001d34e080 000006427fa34749 mscorwks!CreateApplicationContext + 0x41d
000000001d34e0e0 0000064280184902 mscorwks!ReOpenMetaDataWithMemory + 0x1ff59
000000001d34e290 0000064280184532 Company_Common_Diagnostics!Company.Common.Diagnostics.BufferedStream.Write(字节[],的Int32,Int32)将+ 0x1b2
000000001d34e300 00000642801831fd Company_Common_Diagnostics!Company.Common.Diagnostics.XmlRollingTraceListener+TraceWriter.Write(System.String)+0x52
000000001d34e350 00000642801b3304 Company_Common_Diagnostics!Company.Common.Diagnostics.XmlRollingTraceListener.InternalWrite(System.Text.StringBuilder)+0x3d
000000001d34e390 0000064274e9d7ec Company_Common_Diagnostics!Company.Common.Diagnostics.XmlRollingTraceListener.TraceTransfer(System.Diagnostics.TraceEventCache, System.String,的Int32,System.String,的System.Guid)+ 0xc4
000000001d34e410 00000642801b2f59 System_ni!System.Diagnostics.TraceSource.TraceTransfer(的Int32,System.String,的System.Guid)+ 0x2ec
 

解决方案

想通了,我相信。我钻进了BufferStream一看,原来是在一个状态,其中任何召入的TraceListener也只是停留在一个Thread.sleep代码(1)循环。我希望这是解决办法,因为我不能为我的生活重建的问题。

我有usegloballock =虚假和自动冲洗= true在跟踪配置。上的TraceListener的冲洗方法不是线程安全的 - 监听是为了使用数据缓冲,等场合的TraceListener会得到不好的状态,当有刷新的并发性和写入。此修复程序是简单地设置自动冲洗= FALSE。我不能相信我没有赶上这更早。

I have a multithreaded .NET Windows Service that hangs intermittently -- maybe once every two weeks of 24/7 operation. When the hangs occurs the threadpool is completely saturated because calls to our custom tracelistener start blocking for some reason. There aren't any locks in the offending code nor anything blocking according to windbg, but they're definitely blocking somewhere. There aren't any exceptions on the stack either. There is a Thread.Sleep(1) that will occasionally be hit in the BufferedStream.Write code, but my question is what is the ReOpenMetaDataWithMemory, CreateApplicationContext, and DllCanUnloadNow mean?

Nearly all of the 2000 hung up worker threads (not normal operation!) on the ThreadPool have a stack similar to the following:

0:027> !dumpstack
OS Thread Id: 0x1638 (27)
Child-SP         RetAddr          Call Site
000000001d34df58 0000000077d705d6 ntdll!ZwDelayExecution+0xa
000000001d34df60 000006427f88901d kernel32!SleepEx+0x96
000000001d34e000 000006427f454379 mscorwks!DllCanUnloadNowInternal+0xf53d
000000001d34e080 000006427fa34749 mscorwks!CreateApplicationContext+0x41d
000000001d34e0e0 0000064280184902 mscorwks!ReOpenMetaDataWithMemory+0x1ff59
000000001d34e290 0000064280184532 Company_Common_Diagnostics!Company.Common.Diagnostics.BufferedStream.Write(Byte[], Int32, Int32)+0x1b2
000000001d34e300 00000642801831fd Company_Common_Diagnostics!Company.Common.Diagnostics.XmlRollingTraceListener+TraceWriter.Write(System.String)+0x52
000000001d34e350 00000642801b3304 Company_Common_Diagnostics!Company.Common.Diagnostics.XmlRollingTraceListener.InternalWrite(System.Text.StringBuilder)+0x3d
000000001d34e390 0000064274e9d7ec Company_Common_Diagnostics!Company.Common.Diagnostics.XmlRollingTraceListener.TraceTransfer(System.Diagnostics.TraceEventCache, System.String, Int32, System.String, System.Guid)+0xc4
000000001d34e410 00000642801b2f59 System_ni!System.Diagnostics.TraceSource.TraceTransfer(Int32, System.String, System.Guid)+0x2ec

解决方案

Figured it out I believe. I got into the BufferStream and saw that it was in a state where anything that called into the TraceListener would just get stuck in a Thread.Sleep(1) loop. I hope this is the fix because I can't for the life of me recreate the issue.

I had usegloballock=false and autoflush=true in the trace configuration. The flush method on the TraceListener was not thread-safe -- the listener is meant to use data buffering, so on occasion the TraceListener would get in a bad state when there was concurrency of flushes and writes. The fix was to simply set autoflush=false. I can't believe I didn't catch this sooner.

这篇关于WinDbg的 - 的TraceListener和饱和线程池的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆