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

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

2024-2-19 21:15
4266

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

测试部分代码如下:

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

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

另外,分析死锁还有 !locks

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

上面的两个命令基本分析出了死锁的状态,接下来使用 ~*kvn 来查看所有线程的堆栈情况。

根据!cs -l可知OwningThread = 0x0000367c,线程367c拥有临界区Critical section = 0x000750585058,结合上面线程的栈帧发现,当前线程试图进入临界区5070.见4号线程栈帧04第一个参数.同理,有5号线程拥有临界区Critical section = 0x00075070 (CriticalSectionDead!cs2+0x0),但是试图进入4号线程的临界区。综上所述,两个线程各自的拥有的临界区未退出,想要访问对方的临界区而形成交叉,导致自旋锁失败而产生死锁.

点击查看测试工程代码

关于TestDeadLocks.7z起初是想复现 [原创]调试TerminateThread导致的死锁 这位大佬的文章,遇到了现在的问题。

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);
}
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);
}
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
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
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
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
0:006> ~*kvn
 
   0  Id: 3a10.1b00 Suspend: 1 Teb: 00d26000 Unfrozen
 # ChildEBP RetAddr      Args to Child             
00 00f5fd30 76dbada9     000000e8 00000000 00000000 ntdll!NtWaitForSingleObject+0xc (FPO: [3,0,0])
01 00f5fda4 76dbad02     000000e8 ffffffff 00000000 KERNELBASE!WaitForSingleObjectEx+0x99 (FPO: [SEH])
02 00f5fdb8 0007150e     000000e8 ffffffff 0111ef58 KERNELBASE!WaitForSingleObject+0x12 (FPO: [Non-Fpo])
03 00f5fdd0 00071700     00000001 01116cd0 0111ef58 CriticalSectionDead!main+0x4e (FPO: [0,0,4]) (CONV: cdecl) [E:\debug-demo-set\DeadLocks\CriticalSectionDead\main.cpp @ 37]
04 (Inline) --------     -------- -------- -------- CriticalSectionDead!invoke_main+0x1c (Inline Function @ 00071700) (CONV: cdecl) [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 78]
05 00f5fe18 766bfcc9     00d23000 766bfcb0 00f5fe84 CriticalSectionDead!__scrt_common_main_seh+0xfa (FPO: [Non-Fpo]) (CONV: cdecl) [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288]
06 00f5fe28 77327c5e     00d23000 3d12d987 00000000 KERNEL32!BaseThreadInitThunk+0x19 (FPO: [Non-Fpo])
07 00f5fe84 77327c2e     ffffffff 77348c18 00000000 ntdll!__RtlUserThreadStart+0x2f (FPO: [SEH])
08 00f5fe94 00000000     00071788 00d23000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
 
   1  Id: 3a10.ef4 Suspend: 1 Teb: 00d29000 Unfrozen
 # ChildEBP RetAddr      Args to Child             
00 0130f778 772f5bd0     000000c4 01115678 00000010 ntdll!NtWaitForWorkViaWorkerFactory+0xc (FPO: [5,0,0])
01 0130f938 766bfcc9     01114f60 766bfcb0 0130f9a4 ntdll!TppWorkerThread+0x2a0 (FPO: [Non-Fpo])
02 0130f948 77327c5e     01114f60 3cd7dea7 00000000 KERNEL32!BaseThreadInitThunk+0x19 (FPO: [Non-Fpo])
03 0130f9a4 77327c2e     ffffffff 77348c18 00000000 ntdll!__RtlUserThreadStart+0x2f (FPO: [SEH])
04 0130f9b4 00000000     772f5930 01114f60 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
 
   2  Id: 3a10.3524 Suspend: 1 Teb: 00d2c000 Unfrozen
 # ChildEBP RetAddr      Args to Child             
00 0140fd74 772f5bd0     000000c4 01115af0 00000010 ntdll!NtWaitForWorkViaWorkerFactory+0xc (FPO: [5,0,0])
01 0140ff34 766bfcc9     01114f60 766bfcb0 0140ffa0 ntdll!TppWorkerThread+0x2a0 (FPO: [Non-Fpo])
02 0140ff44 77327c5e     01114f60 3ca7d8a3 00000000 KERNEL32!BaseThreadInitThunk+0x19 (FPO: [Non-Fpo])
03 0140ffa0 77327c2e     ffffffff 77348c18 00000000 ntdll!__RtlUserThreadStart+0x2f (FPO: [SEH])
04 0140ffb0 00000000     772f5930 01114f60 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
 
   3  Id: 3a10.38ec Suspend: 1 Teb: 00d2f000 Unfrozen
 # ChildEBP RetAddr      Args to Child             
00 0154f6b0 772f5bd0     000000c4 01116918 00000010 ntdll!NtWaitForWorkViaWorkerFactory+0xc (FPO: [5,0,0])
01 0154f870 766bfcc9     01114f60 766bfcb0 0154f8dc ntdll!TppWorkerThread+0x2a0 (FPO: [Non-Fpo])
02 0154f880 77327c5e     01114f60 3cb3dfdf 00000000 KERNEL32!BaseThreadInitThunk+0x19 (FPO: [Non-Fpo])
03 0154f8dc 77327c2e     ffffffff 77348c18 00000000 ntdll!__RtlUserThreadStart+0x2f (FPO: [SEH])
04 0154f8ec 00000000     772f5930 01114f60 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
 
   4  Id: 3a10.367c Suspend: 1 Teb: 00d32000 Unfrozen
 # ChildEBP RetAddr      Args to Child             
00 0168fae0 7731f999     00075074 00000000 00075070 ntdll!NtWaitForAlertByThreadId+0xc (FPO: [2,0,0])
01 0168fb10 7731f6ed     00000000 00000000 00075070 ntdll!RtlpWaitOnAddressWithTimeout+0x64 (FPO: [Non-Fpo])
02 0168fbb0 7730011a     000713a0 00000001 00000001 ntdll!RtlpWaitOnCriticalSection+0x18d (FPO: [Non-Fpo])
03 0168fbe8 772fff69     00000000 0168fc04 000713ef ntdll!RtlpEnterCriticalSectionContended+0x1aa (FPO: [Non-Fpo])
04 0168fbf4 000713ef     00075070 000713a0 0168fc14 ntdll!RtlEnterCriticalSection+0x49 (FPO: [1,0,0])
05 0168fc04 766bfcc9     00000001 766bfcb0 0168fc70 CriticalSectionDead!DeadlockThread1+0x4f (FPO: [Non-Fpo]) (CONV: cdecl) [E:\debug-demo-set\DeadLocks\CriticalSectionDead\main.cpp @ 12]
06 0168fc14 77327c5e     00000001 3c8fdb73 00000000 KERNEL32!BaseThreadInitThunk+0x19 (FPO: [Non-Fpo])
07 0168fc70 77327c2e     ffffffff 77348c18 00000000 ntdll!__RtlUserThreadStart+0x2f (FPO: [SEH])
08 0168fc80 00000000     000713a0 00000001 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
 
   5  Id: 3a10.338c Suspend: 1 Teb: 00d35000 Unfrozen
 # ChildEBP RetAddr      Args to Child             
00 017cf7c8 7731f999     0007505c 00000000 00075058 ntdll!NtWaitForAlertByThreadId+0xc (FPO: [2,0,0])
01 017cf7f8 7731f6ed     00000000 00000000 00075058 ntdll!RtlpWaitOnAddressWithTimeout+0x64 (FPO: [Non-Fpo])
02 017cf898 7730011a     00071430 00000002 00000002 ntdll!RtlpWaitOnCriticalSection+0x18d (FPO: [Non-Fpo])
03 017cf8d0 772fff69     017cf8e8 0007147f 00075058 ntdll!RtlpEnterCriticalSectionContended+0x1aa (FPO: [Non-Fpo])
04 017cf8d8 0007147f     00075058 00071430 017cf8f8 ntdll!RtlEnterCriticalSection+0x49 (FPO: [1,0,0])
05 017cf8e8 766bfcc9     00000002 766bfcb0 017cf954 CriticalSectionDead!DeadlockThread2+0x4f (FPO: [Non-Fpo]) (CONV: cdecl) [E:\debug-demo-set\DeadLocks\CriticalSectionDead\main.cpp @ 23]
06 017cf8f8 77327c5e     00000002 3c9bde57 00000000 KERNEL32!BaseThreadInitThunk+0x19 (FPO: [Non-Fpo])
07 017cf954 77327c2e     ffffffff 77348c18 00000000 ntdll!__RtlUserThreadStart+0x2f (FPO: [SEH])
08 017cf964 00000000     00071430 00000002 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
 
#  6  Id: 3a10.35dc Suspend: 1 Teb: 00d38000 Unfrozen
 # ChildEBP RetAddr      Args to Child             
00 0190f948 7736dba9     3c77de7b 7736db70 7736db70 ntdll!DbgBreakPoint (FPO: [0,0,0])
01 0190f978 766bfcc9     00000000 766bfcb0 0190f9e4 ntdll!DbgUiRemoteBreakin+0x39 (FPO: [Non-Fpo])
02 0190f988 77327c5e     00000000 3c77dee7 00000000 KERNEL32!BaseThreadInitThunk+0x19 (FPO: [Non-Fpo])
03 0190f9e4 77327c2e     ffffffff 77348c18 00000000 ntdll!__RtlUserThreadStart+0x2f (FPO: [SEH])
04 0190f9f4 00000000     7736db70 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
0:006> ~*kvn
 
   0  Id: 3a10.1b00 Suspend: 1 Teb: 00d26000 Unfrozen

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

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