博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
windbg 常用查看锁以及互斥量
阅读量:4166 次
发布时间:2019-05-26

本文共 1942 字,大约阅读时间需要 6 分钟。



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

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

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

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 可以查看对应的内存地址




转载地址:http://xtqxi.baihongyu.com/

你可能感兴趣的文章
Java集合(4) - HashMap-put()源码解析与常见问题(二)
查看>>
Java集合(5) - HashMap查删源码解析与常见问题(三)
查看>>
Java集合(6) - LinkedHashMap源码解析
查看>>
Java集合(7) - TreeMap源码解析
查看>>
Java集合(8) - Set与AbstractSet源码解析
查看>>
Java多线程(2) - 多线程之线程安全详解(synchronized、Lock)
查看>>
OKR与CFR管理模式(二)-CFR与OKR的绩效管理
查看>>
Java多线程(3) - 多线程之死锁
查看>>
Java多线程(4) - 多线程之Volatile关键字、ThreadLocal、Atomic系列类、CAS
查看>>
Java多线程(5) - 多线程之线程通讯(一)(wait、notify、join、yield、sleep区别与应用)
查看>>
Java多线程(6) - 多线程之线程通讯(二)(wait与notify案例、守护线程)
查看>>
什么是项目管理?怎么管?(二)
查看>>
Java多线程(7) - 多线程之线程停止方式
查看>>
Java设计模式(1) - 单例设计模式多种写法
查看>>
Java设计模式(2) - 工厂设计模式
查看>>
Java多线程(8) - 同步(并发)类容器详解(CopyOnWrite容器、ConcurrentMap容器、Queue队列容器)
查看>>
Java设计模式(3) - 多线程并发设计模式 - Future设计模式
查看>>
Java设计模式(5) - 多线程并发设计模式 - 生产者-消费者设计模式多种写法
查看>>
Java多线程(9) - 多线程 - 线程池详解与使用示例
查看>>
Java多线程(10) - 多线程 - CountDownLatch、CyclicBarrier、Semaphore使用示例详解
查看>>