首页
社区
课程
招聘
WinDbg的 !CS -l 和 !locks 使用练习
发表于: 2024-2-19 21:15 4602

WinDbg的 !CS -l 和 !locks 使用练习

2024-2-19 21:15
4602

最近尝试分析一个程序死锁的问题,发现无论是使用!cs -l 还是 !locks都是没有任何有效的输出,于是怀疑是不是自己的WinDbg版本或环境配置上出了问题,导致了这两个命令失效,所以有了本篇简单的用例来测试WinDbg命令,顺便针对这两个分析线程死锁的高频命令做一个详细的笔记。如果有对WinDbg调试道友,可以加个好友一起讨论讨论。


测试部分代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
CRITICAL_SECTION cs1, cs2;
 
void DeadlockThread1(int threadId)
{
    EnterCriticalSection(&cs1);
    std::cout << "Thread " << threadId << " entered cs1\n";
    Sleep(100); // 让线程暂停一段时间,以便另一个线程有机会执行
    EnterCriticalSection(&cs2);
    std::cout << "Thread " << threadId << " entered cs2\n";
    LeaveCriticalSection(&cs2);
    LeaveCriticalSection(&cs1);
}
 
void DeadlockThread2(int threadId)
{
    EnterCriticalSection(&cs2);
    std::cout << "Thread " << threadId << " entered cs2\n";
    Sleep(100); // 让线程暂停一段时间,以便另一个线程有机会执行
    EnterCriticalSection(&cs1);
    std::cout << "Thread " << threadId << " entered cs1\n";
    LeaveCriticalSection(&cs1);
    LeaveCriticalSection(&cs2);
}

因为两个线程函数同时拉起,导致了临界区死锁问题。
图片描述
使用WinDbg启动程序,并使用命令 !cs -l 进行查看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
0:006> !cs -l
-----------------------------------------
DebugInfo          = 0x773e4a40
Critical section   = 0x00075058 (CriticalSectionDead!cs1+0x0)
LOCKED
LockCount          = 0x1
WaiterWoken        = No
OwningThread       = 0x0000367c
RecursionCount     = 0x1
LockSemaphore      = 0xFFFFFFFF
SpinCount          = 0x020007d0
-----------------------------------------
DebugInfo          = 0x773e4a60
Critical section   = 0x00075070 (CriticalSectionDead!cs2+0x0)
LOCKED
LockCount          = 0x1
WaiterWoken        = No
OwningThread       = 0x0000338c
RecursionCount     = 0x1
LockSemaphore      = 0xFFFFFFFF
SpinCount          = 0x020007d0

分析命令输出各字段的含义:

  • !cs -l 是一个 WinDbg 的扩展命令,用于列出所有当前存在的临界区以及它们的状态。
  • Critical Section 这行显示了一个临界区的地址,以及它属于哪个模块和哪个临界区变量。在这里,临界区属于 CriticalSectionDead 模块,并且它的名字是 cs1。
  • LockCount 表示这个临界区被锁定的次数。
  • SpinCount 表示在尝试获取临界区锁定时,线程会进行自旋(忙等待)的次数。如果自旋后仍然无法获取锁,线程就会进入睡眠状态。
  • OwningThread 显示当前拥有这个临界区的线程的线程 ID。
  • RecursionCount 表示拥有这个临界区的线程已经重新进入这个临界区的次数。在某些情况下,一个线程可能会多次进入同一个临界区,这个计数就是用来跟踪这种情况的。

另外,分析死锁还有 !locks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
0:006> !locks
 
CritSec CriticalSectionDead!cs1+0 at 00075058
WaiterWoken        No
LockCount          1
RecursionCount     1
OwningThread       367c
EntryCount         0
ContentionCount    1
*** Locked
 
CritSec CriticalSectionDead!cs2+0 at 00075070
WaiterWoken        No
LockCount          1
RecursionCount     1
OwningThread       338c
EntryCount         0
ContentionCount    1
*** Locked
 
Scanned 5 critical sections

[招生]科锐逆向工程师培训(2025年3月11日实地,远程教学同时开班, 第52期)!

最后于 2024-2-19 22:31 被_THINCT编辑 ,原因:
上传的附件:
收藏
免费 1
支持
分享
最新回复 (1)
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
哈喽,请问作者用的是什么版本的windbg,我是用x64的这两个命令用不了
2024-7-12 18:03
0
游客
登录 | 注册 方可回帖
返回