18.windbg-临界区leak案例
来源:互联网 发布:ip网络广播系统设计厂 编辑:程序博客网 时间:2024/06/06 14:28
示例代码:
#include "windows.h"#include <stdio.h>#include <tchar.h>CRITICAL_SECTION g_cs;DWORD WINAPI ThreadProc1(LPVOID lpParameter){EnterCriticalSection(&g_cs);printf("thread1\n");return 0;}DWORD WINAPI ThreadProc2(LPVOID lpParameter){EnterCriticalSection(&g_cs);printf("thread2\n");return 0;}int _tmain(int argc, _TCHAR* argv[]){InitializeCriticalSection(&g_cs);CreateThread(NULL,NULL,ThreadProc1,NULL,NULL,NULL);Sleep(1000);CreateThread(NULL,NULL,ThreadProc2,NULL,NULL,NULL);getchar();return 0;}
编译成release,运行,windbg强制附加:
0:002> ~*kb 0 Id: 10c4.a18 Suspend: 1 Teb: 7ffdf000 UnfrozenChildEBP RetAddr Args to Child 0012fc8c 7c92daea 7c932298 00000018 0012fcf0 ntdll!KiFastSystemCallRet0012fc90 7c932298 00000018 0012fcf0 0012fcf0 ntdll!ZwRequestWaitReplyPort+0xc0012fcb0 7c872a51 00000000 00260688 0002021d ntdll!CsrClientCallServer+0x8c0012fdac 7c872b98 00000003 785bc660 00001000 kernel32!ReadConsoleInternal+0x1be0012fe34 7c8018b7 00000003 785bc660 00001000 kernel32!ReadConsoleA+0x3b0012fe8c 78588ef2 00000003 785bc660 00001000 kernel32!ReadFile+0x640012fed0 78589376 00000000 785bc660 00001000 MSVCR90!_read_nolock+0x203 [f:\dd\vctools\crt_bld\self_x86\crt\src\read.c @ 233]0012ff14 7854efd2 00000000 785bc660 00001000 MSVCR90!_read+0xc0 [f:\dd\vctools\crt_bld\self_x86\crt\src\read.c @ 93]0012ff30 7854e4fe 785b73a8 0165941f 00403390 MSVCR90!_filbuf+0x7d [f:\dd\vctools\crt_bld\self_x86\crt\src\_filbuf.c @ 136]0012ff68 7854e557 785b73a8 0040108c 00000001 MSVCR90!getc+0xe0 [f:\dd\vctools\crt_bld\self_x86\crt\src\fgetc.c @ 49]0012ff70 0040108c 00000001 00001650 004011fa MSVCR90!_fgetchar+0xb [f:\dd\vctools\crt_bld\self_x86\crt\src\fgetchar.c @ 37]WARNING: Stack unwind information not available. Following frames may be wrong.0012ffc0 7c817077 80000001 03edd9e4 7ffd9000 test2+0x108c0012fff0 00000000 00401342 00000000 78746341 kernel32!BaseProcessStart+0x23 1 Id: 10c4.1650 Suspend: 1 Teb: 7ffde000 UnfrozenChildEBP RetAddr Args to Child 0050ff18 7c92df5a 7c939b23 0000002c 00000000 ntdll!KiFastSystemCallRet0050ff1c 7c939b23 0000002c 00000000 00000000 ntdll!NtWaitForSingleObject+0xc0050ffa4 7c921046 00403370 0040102b 00403370 ntdll!RtlpWaitForCriticalSection+0x1320050ffac 0040102b 00403370 7c80b729 00000000 ntdll!RtlEnterCriticalSection+0x46WARNING: Stack unwind information not available. Following frames may be wrong.0050ffec 00000000 00401020 00000000 00000000 test2+0x102b# 2 Id: 10c4.1a70 Suspend: 1 Teb: 7ffdd000 UnfrozenChildEBP RetAddr Args to Child 003bffc8 7c972119 00000005 00000004 00000001 ntdll!DbgBreakPoint003bfff4 00000000 00000000 00000000 00000000 ntdll!DbgUiRemoteBreakin+0x2d
注意到1线程在等待临界区,对临界区继续分析:
0:002> !cs 00403370 -----------------------------------------Critical section = 0x00403370 (test2+0x3370)DebugInfo = 0x7c99e9c0LOCKEDLockCount = 0x1OwningThread = 0x0000155cRecursionCount = 0x1LockSemaphore = 0x2CSpinCount = 0x000000000:002> ~~[0x0000155c] ^ Illegal thread error in '~~[0x0000155c]'
竟然是错误的线程,这说明这个破线程没有调用LeaveCriticalSection就挂了!
继续分析,找出原因:
Application Verifier 是类似pageheap 的工具,使用范围更广。可以通过Application Verifier
方便设定注册表,让操作系统主动地提供关于handle, critical section, heap 等系统层面的调试
信息.
在这里有下载:http://www.microsoft.com/en-us/download/details.aspx?id=20028
启动Application Verifier 后,添加程序名字,然后勾选Locks。在windbg 中用ctrl+E 打开这个程序重新运行
windbg中断了:
0:000> g=======================================VERIFIER STOP 00000200: pid 0xA28: Thread cannot own a critical section. 00000CFC : Thread ID.00403370 : Critical section address.002A8250 : Critical section debug information address.00000000 : Critical section initialization stack trace.=======================================This verifier stop is continuable.After debugging it use `go' to continue.=======================================(a28.cfc): Break instruction exception - code 80000003 (first chance)eax=002a82a8 ebx=00387d08 ecx=00000001 edx=01caface esi=00000000 edi=002a82a8eip=7c92120e esp=01cafb58 ebp=01cafd5c iopl=0 nv up ei pl nz na po nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202ntdll!DbgBreakPoint:7c92120e cc int 3
原因很明显:Thread cannot own a critical section.线程ID是cfc
0:001> ~~[00000CFC]. 1 Id: a28.cfc Suspend: 1 Teb: 7ffde000 Unfrozen Start: kernel32!BaseThreadStartThunk (7c8106f9) Priority: 0 Priority class: 32 Affinity: f0:001> ~1kbChildEBP RetAddr Args to Child 01cafb54 10003b68 11ca2a3c 00000000 002a8250 ntdll!DbgBreakPoint01cafd5c 0037c427 003860c8 00000200 00000cfc vrfcore!VerifierStopMessageEx+0x4d101cafe00 0037c47e 00403370 002a8250 fffffffe vfbasics!AVrfpCheckCriticalSection+0x16901cafe20 0037c5f2 018e1a90 fffffffe 00000000 vfbasics!AVrfpCheckCriticalSectionSplayNode+0x3401caff48 0037c6a9 018e1888 fffffffe 00000000 vfbasics!AVrfpCheckCriticalSectionTree+0x4701caff64 00384002 fffffffe 00000000 00000000 vfbasics!AVrfCheckForOrphanedCriticalSections+0x7501caff78 00384020 fffffffe 00384314 01f29440 vfbasics!AVrfpCheckThreadTermination+0x1101caff80 00384314 01f29440 7c92e920 7c98b127 vfbasics!AVrfpCheckCurrentThreadTermination+0x1501caffb4 7c80b729 018e1af8 7c92e920 7c98b127 vfbasics!AVrfpStandardThreadFunction+0x4c01caffec 00000000 003842c8 018e1af8 00000000 kernel32!BaseThreadStart+0x37
这些破函数我也不认识,但是我认识这些:CheckThreadTermination CheckCriticalSection!!!这里可以看到,线程1试图退出当前线程,但是由于还拥有没有释放的CriticalSection,所以在激活Application Verifier 后,就会自动产生一个break point exception.
- 18.windbg-临界区leak案例
- Windbg跟踪临界区的BUG
- Memory Leak Detection Using Windbg
- 临界资源 & 临界区
- 临界段临界区
- 使用windbg找内存泄露(memory leak)
- 使用windbg找内存泄露(memory leak)
- Memory Leak Detection Using Windbg(windbg检查内存泄漏)
- 临界区
- 临界区
- 临界区
- 临界区
- 临界区
- 临界区
- 临界区
- 临界区
- 临界区
- 临界区
- Oracle中查找和删除重复记录方法简介
- 数据驱动组件
- HDUOJ Minimum Inversion Number
- 官方NotePad实例学习--ListActivity的使用
- tableView的一些函数
- 18.windbg-临界区leak案例
- 浅谈系统设计中的抽象和具体
- Php设计模式之工厂模式(一)简单工厂模式
- stackless python的疑问
- nginx:expires控制页面缓存以及加头
- 仅通过崩溃地址找出源代码的出错行
- Php设计模式之工厂模式(二)【工厂方法模式 Factory Method】
- 教你如何迅速秒杀掉:99%的海量数据处理面试题
- Oracle 创建用户