windbg 常用查看锁以及互斥量

本文深入探讨了死锁的概念及产生的原因,详细解释了死锁的四个必要条件,并介绍了操作系统中用于检测和诊断死锁的相关工具和技术。


操作系统对死锁的描述如下:

所谓死锁:是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。   

那么为什么会产生死锁呢?

1.因为系统资源不足。

2.进程运行推进的顺序不合适。   

3.资源分配不当。            

而产生死锁的条件有四个:

1.互斥条件:所谓互斥就是进程在某一时间内独占资源。

2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

3.不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺。

4.循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。


!locks 可以查看所有线程占用的锁信息,包含拥有锁的线程,以及有多少个线程在等待这把锁!

ntdll!RtlEnterCriticalSection的第一个参数就代表的互斥量或锁,可以通过!cs xxxxxxx 可以看到对应的互斥量信息(包含拥有这个锁的线程ID以及对应的信号量)

底层的临界区数据结构为_RTL_CRITICAL_SECTION,所以也可以通过dt命令去查看dt ntdll!_RTL_CRITICAL_SECTION 004030f4,获取到的信息和!cs 004030f4基本是一致的!

0:006>  dt ntdll!_RTL_CRITICAL_SECTION
   +0x000 DebugInfo        : Ptr64 _RTL_CRITICAL_SECTION_DEBUG
   +0x008 LockCount        : Int4B
   +0x00c RecursionCount   : Int4B
   +0x010 OwningThread     : Ptr64 Void
   +0x018 LockSemaphore    : Ptr64 Void
   +0x020 SpinCount        : Uint8B

LockCount默认为-1,如果>=0,则表示有线程进入到临界区,要找出有多少线程正在等待进入临界区,可以:

正在等待的线程数量=LockCount - RecursionCount + 1。

RecursionCount:表示同一个线程进入到临界区多少次,默认为0。

OwningThread:如果有线程进入到临界区,这是进入临界区的线程ID。

LockSemaphore:这是一个自动重置事件,当线程试图进入一个其他线程占用的临界区时,将会创建这个事件。

SpinCount:自旋锁的次数。


进一步看DebugInfo结构:

0:001> dt _RTL_CRITICAL_SECTION_DEBUG  
02.ntdll!_RTL_CRITICAL_SECTION_DEBUG  
03.   +0x000 Type             : Uint2B  
04.   +0x002 CreatorBackTraceIndex : Uint2B  
05.   +0x004 CriticalSection  : Ptr32 _RTL_CRITICAL_SECTION  
06.   +0x008 ProcessLocksList : _LIST_ENTRY  
07.   +0x010 EntryCount       : Uint4B  
08.   +0x014 ContentionCount  : Uint4B  
09.   +0x018 Flags            : Uint4B  
10.   +0x01c CreatorBackTraceIndexHigh : Uint2B  
11.   +0x01e SpareUSHORT      : Uint2B  

CriticalSection:在这个域上包含敢一个指针指向与这个结构相关的临界区。

ProcessLocksList:任何进程在操作系统中都将维护一张链表,其中包含了在这个进程中所有处于活跃状态的临界区,你可以通过这个节点中FLINK和BLINK来遍历进程中的临界区链表。

EntryCount:每当线程尝试进入一个已经被其他线程拥有的临界区并由此进入到等待状态,这个域的值都会被加1。


ntdll!NtWaitForSingleObject

NTSTATUS WINAPI NtWaitForSingleObject(   _In_  HANDLE Handle,   _In_  BOOLEAN Alertable,   _In_  PLARGE_INTEGER Timeout ); 
第一个参数句柄 可以通过!handle xxx f去查看详细的信息 

?ntdll!__RtlUserThreadStart+0x20 可以查看对应的内存地址








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值