有没有Windows中的RTL_CRITICAL_SECTION结构的LockCount字段可以合法地为负的情况?
我们正在跟踪一个非常难以捉摸的崩溃,我们看到的一个症状是一个负LockCount的CS。 在发生事故的时候,计数是-6,但似乎一般是-1,-2等。
在此之前,我们假设这是一个非常糟糕的事情发生,我只是想validation这个假设是正确的。 我可以find关于RTL_CRITICAL_SECTION的内部工作的信息。
在某些Windows版本上,负锁计数是正常行为。 请注意,此字段的含义在Windows的生命周期中已更改(请参阅下文)。
解释这些私人领域是一件棘手的事情,您可能会从使用专用的关键部分调试工具中受益。
例如,看到这个MSDN文章给出了一些细节。 特别是我认为这说明了为什么-6的值是完全合理的。
一些相关的摘录:
关键部分可以通过各种不同的方法在用户模式下显示。 每个字段的确切含义取决于您使用的Microsoft Windows版本的版本。
……
在Microsoft Windows 2000和Windows XP中,LockCount字段表示任何线程已为此关键部分调用EnterCriticalSection例程的次数减1。 该字段从-1开始为未锁定的关键部分。 EnterCriticalSection的每次调用都会增加此值; LeaveCriticalSection的每次调用递减它。 例如,如果LockCount为5,则此关键部分被锁定,一个线程获取它,另外五个线程正在等待此锁定。
……
在Microsoft Windows server 2003 Service Pack 1和更高版本的Windows中,LockCount字段被解析如下:
- 最低位显示锁定状态。 如果这个位是0,临界区被锁定; 如果是1,临界区没有锁定。
- 下一个位显示一个线程是否被这个锁唤醒。 如果这个位是0,那么一个线程已经被这个锁唤醒; 如果是1,没有线程被唤醒。
- 剩余的位是等待锁的线程数的一个补码。
然后接着解释如何解释-22
的锁定计数。 所以,总而言之,这比你想象的更复杂!
从这里 ,是一个部分的解释:
LockCount这是关键部分中最重要的领域。 它初始化为-1; 0或更大的值表示关键部分被持有或拥有。 当它不等于-1时,OwningThread字段(该字段在WINNT.H中错误地定义,它应该是一个DWORD而不是一个HANDLE)包含拥有这个关键部分的线程ID。 此字段与(RecursionCount -1)的值之间的差值表示有多少额外的线程正在等待获取关键部分。