gpt4 book ai didi

c# - 使用 ReaderWriterLockSlim 调试死锁

转载 作者:行者123 更新时间:2023-11-30 12:27:15 25 4
gpt4 key购买 nike

我正在调试针对 .NET 3.5 的托管应用程序中的挂起。其中一个线程永远等待方法 System.Threading.ReaderWriterLockSlim.EnterWriteLock。为了找出哪个线程拥有锁,我检查了 internal member field ReaderWriterCount[] rwc ReaderWriterLockSlim 类及其包含的所有 ReaderWriterCountRecursiveCounts 对象。这些对象包含有关所有线程的信息。除了包含 readercount=1 的单个对象外,所有对象都包含 writercount=0readercount=0:

[53] 0144fc84
Name: System.Threading.ReaderWriterCount
MethodTable: 6bb4e930
EEClass: 6b9ba4d0
Size: 24(0x18) bytes
(C:\Windows\assembly\GAC_MSIL\System.Core\3.5.0.0__b77a5c561934e089\System.Core.dll)
Fields:
MT Field Offset Type VT Attr Value Name
55782f94 4000625 c System.Int32 1 instance 53 threadid
55782f94 4000626 10 System.Int32 1 instance 1 readercount
6bb4e930 4000627 4 ...ReaderWriterCount 0 instance 00000000 next
6bb4e858 4000628 8 ...g.RecursiveCounts 0 instance 0144fc9c rc

AFAIU 这意味着 MTID 为 53 的线程拥有锁。我用 kb 将它转储到堆栈(!clrstack 失败,因为它不是托管线程)并得到以下信息:

ChildEBP RetAddr  Args to Child              
16eee9b4 765c14ab 00000280 00000000 16eee9fc ntdll!ZwWaitForSingleObject+0x15
16eeea20 778d1194 00000280 00009c40 00000000 KERNELBASE!WaitForSingleObjectEx+0x98
16eeea38 681954d7 00000280 00009c40 00000000 KERNEL32!WaitForSingleObjectExImplementation+0x75
16eeea7c 68195423 00000280 00009c40 00000000 mscorwks!PEImage::LoadImage+0x1af
16eeeacc 68195442 00009c40 00000000 00000000 mscorwks!CLREvent::WaitEx+0x117
16eeeae0 681d95c7 00009c40 00000000 00000000 mscorwks!CLREvent::Wait+0x17
16eeeb60 681d9a55 03376058 00009c40 00000000 mscorwks!ThreadpoolMgr::SafeWait+0x73
16eeebc4 68226508 00000000 00000000 00000000 mscorwks!ThreadpoolMgr::WorkerThreadStart+0x11c
16eefa64 778d338a 04b2e5c8 16eefab0 77e09f72 mscorwks!Thread::intermediateThreadProc+0x49
16eefa70 77e09f72 04b2e5c8 6aecf560 00000000 KERNEL32!BaseThreadInitThunk+0xe
16eefab0 77e09f45 682264c2 04b2e5c8 00000000 ntdll!__RtlUserThreadStart+0x70
16eefac8 00000000 682264c2 04b2e5c8 00000000 ntdll!_RtlUserThreadStart+0x1b

这意味着它是一个 Idle CLR Worker Thread .

我的第一个想法是当读者锁并不总是释放时,应用程序代码中存在错误。但是假设没有得到证实,因为代码在 ReaderWriterLockSlim.EnterWriteLock 上使用了包装器,如下所示:

readerWriterLockSlim.EnterReadLock();

try
{
return executeFunc();
}
finally
{
readerWriterLockSlim.ExitReadLock();
}

finally block 必须保证锁总是被释放。

有没有想过这种情况是如何发生的?线程能否在获取锁之后但在 finally 之前以某种方式中止,然后成为空闲线程池线程?可能是如何缩小问题范围的提示?

附言这个死锁只重现了一次,我只有一个内存转储,因此我不能轻易地说在锁周围添加跟踪或断点并对此进行试验。

最佳答案

试试 !sosex.dlk 和/或 !mlocks 和 !mwaits。这应该会告诉您发生了什么。

关于c# - 使用 ReaderWriterLockSlim 调试死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25833635/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com