windbg 经典死锁调试
代码
// Deadlock_Debug.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "windows.h" #include <process.h> // All the thread must get all of critial_section // Classic Deadlock CRITICAL_SECTION gCritSecFirst; CRITICAL_SECTION gCritSecSecond; CRITICAL_SECTION gCritSecThird; unsigned __stdcall Thread1Func(void* dummy) { printf("Enter Thread 1 \n"); EnterCriticalSection(&gCritSecThird); { Sleep(5000); EnterCriticalSection(&gCritSecFirst); EnterCriticalSection(&gCritSecSecond); LeaveCriticalSection(&gCritSecSecond); LeaveCriticalSection(&gCritSecFirst); } LeaveCriticalSection(&gCritSecThird); printf("Exit thread func 1 \n"); return 1; } unsigned __stdcall Thread2Func(void* dummy) { printf("Enter Thread 2 \n"); EnterCriticalSection(&gCritSecFirst); EnterCriticalSection(&gCritSecSecond); { Sleep(2000); EnterCriticalSection(&gCritSecThird); Sleep(5000); LeaveCriticalSection(&gCritSecThird); } LeaveCriticalSection(&gCritSecSecond); LeaveCriticalSection(&gCritSecFirst); printf("Exit thread func 2 \n"); return 1; } int _tmain(int argc, _TCHAR* argv[]) { unsigned threadID; InitializeCriticalSection(&gCritSecFirst); InitializeCriticalSection(&gCritSecSecond); InitializeCriticalSection(&gCritSecThird); _beginthreadex( NULL, 0, &Thread1Func, NULL, 0, &threadID ); _beginthreadex( NULL, 0, &Thread2Func, NULL, 0, &threadID ); while(1); return 0; }
这是一个经典死锁,开启两个线程,一个以123的次序拿锁,一个以321次序拿锁,互相等待着对方的锁而均不释放自己手中的锁。(此处锁也指CriticalSection)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | 开启WINDBG 附加死锁进程,查看 0:003> ~* kv 0 Id: 2b8.2f0 Suspend: 1 Teb: 7ffdf000 Unfrozen ChildEBP RetAddr Args to Child WARNING: Stack unwind information not available. Following frames may be wrong. 0012ff6c 0042e346 00000001 003c30b8 003c3168 Deadlock_Debug+0x2d85c 0012ffb8 0042e21f 0012fff0 7c816d4f 0007da50 Deadlock_Debug+0x2e346 0012ffc0 7c816d4f 0007da50 7c92e1fe 7ffd9000 Deadlock_Debug+0x2e21f 0012fff0 00000000 0042b523 00000000 78746341 kernel32!BaseProcessStart+0x23 (FPO: [Non-Fpo]) 1 Id: 2b8.1e0 Suspend: 1 Teb: 7ffde000 Unfrozen ChildEBP RetAddr Args to Child 0059fe00 7c92e9c0 7c93901b 00000030 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0]) 0059fe04 7c93901b 00000030 00000000 00000000 ntdll!ZwWaitForSingleObject+0xc (FPO: [3,0,0]) 0059fe8c 7c92104b 004944f0 0042d5e0 004944f0 ntdll!RtlpWaitForCriticalSection+0x132 (FPO: [1,26,4]) 0059fe94 0042d5e0 004944f0 57565554 5b5a5958 ntdll!RtlEnterCriticalSection+0x46 (FPO: [1,0,0]) WARNING: Stack unwind information not available. Following frames may be wrong. 0059ff6c 0042e123 00000000 2d7b25f9 57565554 Deadlock_Debug+0x2d5e0 0059ffa8 0042e094 00000000 0059ffec 7c80b50b Deadlock_Debug+0x2e123 0059ffb4 7c80b50b 003c2c20 57565554 5b5a5958 Deadlock_Debug+0x2e094 0059ffec 00000000 0042dff0 003c2c20 00000000 kernel32!BaseThreadStart+0x37 (FPO: [Non-Fpo]) 2 Id: 2b8.1e4 Suspend: 1 Teb: 7ffdd000 Unfrozen ChildEBP RetAddr Args to Child 0069fe00 7c92e9c0 7c93901b 00000034 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0]) 0069fe04 7c93901b 00000034 00000000 00000000 ntdll!ZwWaitForSingleObject+0xc (FPO: [3,0,0]) 0069fe8c 7c92104b 004944c0 0042d714 004944c0 ntdll!RtlpWaitForCriticalSection+0x132 (FPO: [1,26,4]) 0069fe94 0042d714 004944c0 57565554 5b5a5958 ntdll!RtlEnterCriticalSection+0x46 (FPO: [1,0,0]) WARNING: Stack unwind information not available. Following frames may be wrong. 0069ff6c 0042e123 00000000 2d4b25f9 57565554 Deadlock_Debug+0x2d714 0069ffa8 0042e094 00000000 0069ffec 7c80b50b Deadlock_Debug+0x2e123 0069ffb4 7c80b50b 003c2e60 57565554 5b5a5958 Deadlock_Debug+0x2e094 0069ffec 00000000 0042dff0 003c2e60 00000000 kernel32!BaseThreadStart+0x37 (FPO: [Non-Fpo]) # 3 Id: 2b8.948 Suspend: 1 Teb: 7ffdc000 Unfrozen ChildEBP RetAddr Args to Child 0038ffc8 7c9707a8 00000005 00000004 00000001 ntdll!DbgBreakPoint (FPO: [0,0,0]) 0038fff4 00000000 00000000 00000000 00000000 ntdll!DbgUiRemoteBreakin+0x2d (FPO: [Non-Fpo]) //////////////////////////////////////////////////// 在切换到线程2 1进行观察 可以看到均是在等待CriticalSection 0:003> ~2 kv ChildEBP RetAddr Args to Child 0069fe00 7c92e9c0 7c93901b 00000034 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0]) 0069fe04 7c93901b 00000034 00000000 00000000 ntdll!ZwWaitForSingleObject+0xc (FPO: [3,0,0]) 0069fe8c 7c92104b 004944c0 0042d714 004944c0 ntdll!RtlpWaitForCriticalSection+0x132 (FPO: [1,26,4]) 0069fe94 0042d714 004944c0 57565554 5b5a5958 ntdll!RtlEnterCriticalSection+0x46 (FPO: [1,0,0] 0:003> ~1 kv ChildEBP RetAddr Args to Child 0059fe00 7c92e9c0 7c93901b 00000030 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0]) 0059fe04 7c93901b 00000030 00000000 00000000 ntdll!ZwWaitForSingleObject+0xc (FPO: [3,0,0]) 0059fe8c 7c92104b 004944f0 0042d5e0 004944f0 ntdll!RtlpWaitForCriticalSection+0x132 (FPO: [1,26,4]) 0059fe94 0042d5e0 004944f0 57565554 5b5a5958 ntdll!RtlEnterCriticalSection+0x46 (FPO: [1,0,0]) ////////////////////////////////////////////// 使用!LOCKS指令查看当前的锁 0:003> !locks CritSec Deadlock_Debug+944f0 at 004944f0 LockCount 1 RecursionCount 1 OwningThread 1e4 EntryCount 1 ContentionCount 1 *** Locked CritSec Deadlock_Debug+944d8 at 004944d8 LockCount 0 RecursionCount 1 OwningThread 1e4 EntryCount 0 ContentionCount 0 *** Locked CritSec Deadlock_Debug+944c0 at 004944c0 LockCount 1 RecursionCount 1 OwningThread 1e0 EntryCount 1 ContentionCount 1 *** Locked |
比对线程等待的锁 及个锁的拥有者和锁定情况变可以判断
线程编号1e4 也就是线程2 等待004944c0 的锁(根据堆栈的RtlEnterCriticalSection函数部分查看)
0069fe94 0042d714 004944c0 57565554 5b5a5958 ntdll!RtlEnterCriticalSection+0x46 (FPO: [1,0,0])
而004844c0的锁由线程编号1e0 就是线程1持有
而线程编号1e0 就是线程1 等待004944f0 的锁 该所有线程编号1e4持有
0059fe94 0042d5e0 004944f0 57565554 5b5a5958 ntdll!RtlEnterCriticalSection+0x46 (FPO: [1,0,0])
死锁!!!
找到原因就好修正了。
作 者: itdef
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力


分类:
windows 内核
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话