首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WinDbg -- TraceListener和饱和ThreadPool

WinDbg -- TraceListener和饱和ThreadPool
EN

Stack Overflow用户
提问于 2009-01-27 20:40:33
回答 4查看 2K关注 0票数 0

我有一个多线程的.NET窗口服务,它间歇性地挂起--可能每两周24/7运行一次。当挂起发生时,线程池完全饱和,因为对我们的自定义跟踪程序的调用由于某种原因而开始阻塞。根据windbg的说法,违规代码中没有任何锁,也没有任何阻塞,但它们肯定在某个地方阻塞了。堆栈上也没有任何异常。在BufferedStream.Write代码中偶尔会遇到一个Thread.Sleep(1),但我的问题是ReOpenMetaDataWithMemory、CreateApplicationContext和DllCanUnloadNow是什么意思?

几乎所有2000个工作线程都挂起了(非正常操作!)在ThreadPool上有一个类似于以下内容的堆栈:

代码语言:javascript
复制
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
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-01-27 23:39:43

我想我想通了。我进入BufferStream,发现它处于这样一种状态:任何调用到TraceListener的东西都会被卡在Thread.Sleep(1)循环中。我希望这是修复,因为我不能在我的生活中重现这个问题。

我在跟踪配置中使用了usegloballock=false和autoflush=true。TraceListener上的flush方法不是线程安全的--侦听器需要使用数据缓冲,因此当同时存在刷新和写入时,TraceListener有时会处于糟糕的状态。修复方法是简单地设置autoflush=false。我真不敢相信我没能早点发现。

票数 0
EN

Stack Overflow用户

发布于 2009-02-21 23:33:20

不是真正的答案,但有些东西需要检查...

确保您的跟踪源中没有注册DefaultTraceListener。如果你不显式的删除DefaultTraceListener或或,它可能仍然存在。DefaultTraceListenerIsThreadSafe属性返回false,在这种情况下,System.Diagnostics.Trace类在TraceEvent()调用周围创建一个()锁。

只是一些需要注意的东西。

更多信息:

TraceListener.IsThreadSafe Property

IsThreadSafe的值用于确定在写入侦听器时是否使用全局锁。如果IsThreadSafe的值为false,则无论UseGlobalLock的值是什么,都将使用全局锁。仅当IsThreadSafe的值为true且UseGlobalLock的值为false时,才不使用全局锁。默认行为是在写入侦听器时使用全局锁。

谢谢,亚伦

票数 2
EN

Stack Overflow用户

发布于 2009-01-27 21:37:36

事实上,进入这些函数的偏移量似乎太大了( mscorwks !ReOpenMetaDataWithMemory+0x1ff59),我要说的是,你没有mscorwks的符号。

使用以下命令设置本地符号存储区:

.symfix+ c:\websymbols

.reload mscorwks.dll

其中c:\websymbols是您为系统符号选择的路径。这应该会为您提供合理的函数名,kernel32!Sleep就是从这些函数中调用的。

至于其余的,所有其他挂起的线程的堆栈是什么样子的?另外,你也可以发布一个本机堆栈(kb)吗?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/485130

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档