Windbg
在开始用
0012f1d4 0012f2c8 0012f2dc 0012f200 7c9237bf
0012f1e4 0012f2c8 0012ffb0 0012f2dc 0012f29c
0012f1f4 0012f814 7c9237d8 0012ffb0 0012f2b0
0012f204 7c92378b 0012f2c8 0012ffb0 0012f2dc
0012f214 0012f29c 00402218 00000001 0012f2c8
0012f224 0012ffb0 7c957860 0012f2c8 0012ffb0
0012f234 0012f2dc 0012f29c 00402218 0012f600
0012f244 0012f2c8 00144c90 00230fd2 00000001
5.利用
eax=00000000 ebx=00000000 ecx=0012fe74 edx=00000000 esi=00144c90 edi=0012f600
eip=00401caf esp=0012f5a8 ebp=0012f600 iopl=0 nv up ei pl nz ac pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010216
JustTest!CJustTestDlg::OnButton1+0x2f:
00401caf f77df4 idiv eax,dword ptr [ebp-0Ch] ss:0023:0012f5f4=00000000
6.利用
二.死锁
有人说:多线程是万恶的根源。确实,在多线程编程中有两类 问题是不容易处理的。一:死锁,二:共享资源保护。
但是对于死锁,借助
. 0 Id: 1a04.109c Suspend: 1 Teb: 7ffdf000 Unfrozen
ChildEBP RetAddr Args to Child
0012f510 7c92e9c0 7c93901b 00000780 00000000 ntdll!KiFastSystemCallRet
0012f514 7c93901b 00000780 00000000 00000000 ntdll!ZwWaitForSingleObject+0xc
0012f59c 7c92104b 00416868 0040237d 00416868 ntdll!RtlpWaitForCriticalSection+0x132
0012f5a4 0040237d 00416868 0012f8a0 00144c90 ntdll!RtlEnterCriticalSection+0x46
0012f600 5f4398cc 0012f8a0 00144c90 00000000 JustTest!CJustTestDlg::OnButton1+0x6d [D:testJustTestJustTestDlg.cpp @ 191]
1 Id: 1a04.1288 Suspend: 1 Teb: 7ffde000 Unfrozen
ChildEBP RetAddr Args to Child
00d5fef0 7c92d85c 7c8023ed 00000000 00d5ff24 ntdll!KiFastSystemCallRet
00d5fef4 7c8023ed 00000000 00d5ff24 00d5ffb4 ntdll!NtDelayExecution+0xc
00d5ff4c 7c802451 00002710 00000000 00d5ffb4 kernel32!SleepEx+0x61
00d5ff5c 00401ca9 00002710 74680000 746800e0 kernel32!Sleep+0xf
00d5ffb4 7c80b50b 00000000 74680000 746800e0 JustTest!WndProc+0x39 [D:testJustTestJustTestDlg.cpp @ 179]
00d5ffec 00000000 00401087 00000000 00000000 kernel32!BaseThreadStart+0x37
该示例程序有两个活动线程,但是此时这个示例程序对于用户的任何操作均未响应,可以判断这个程序死锁了。
根据线程
—————————————–
DebugInfo = 0x0014e8d8
Critical section = 0x00416868 (JustTest!g_cs+0x0)
LOCKED
LockCount = 0x1
OwningThread = 0x00001288
RecursionCount = 0x1
LockSemaphore = 0x780
SpinCount = 0x00000000
OwningThread DbgId = ~1s
OwningThread Stack =
ChildEBP RetAddr Args to Child
00d5fef0 7c92d85c 7c8023ed 00000000 00d5ff24 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
00d5fef4 7c8023ed 00000000 00d5ff24 00d5ffb4 ntdll!NtDelayExecution+0xc (FPO: [2,0,0])
00d5ff4c 7c802451 00002710 00000000 00d5ffb4 kernel32!SleepEx+0x61 (FPO: [Non-Fpo])
00d5ff5c 00401ca9 00002710 74680000 746800e0 kernel32!Sleep+0xf (FPO: [1,0,0])
00d5ffb4 7c80b50b 00000000 74680000 746800e0 JustTest!WndProc+0x39 (CONV: stdcall)
00d5ffec 00000000 00401087 00000000 00000000 kernel32!BaseThreadStart+0x37 (FPO: [Non-Fpo])
从以上命令执行结果分析,线程
THREAD 88d9a590 Cid 0c84.0f1c Teb: 7ffde000 Win32Thread: e4e858e8 WAIT: (WrUserRequest) UserMode Non-Alertable
8900b5a8 SynchronizationEvent
Not impersonating
DeviceMap e1713878
Owning Process 0 Image:
Attached Process 88d9c8b0 Image: JustTest.exe
Wait Start TickCount 204830 Ticks: 24996 (0:00:06:30.562)
Context Switch Count 2836 LargeStack
UserTime 00:00:00.046
KernelTime 00:00:00.046
Win32 Start Address 0x004020d0
Start Address 0x7c810867
Stack Init a98a1000 Current a98a0c20 Base a98a1000 Limit a989b000 Call 0
Priority 10 BasePriority 8 PriorityDecrement 0 DecrementCount 16
Kernel stack not resident.
综合以上内容分析
修改注册表使操作系统对每一次内存分配操作时的调用栈进行记录
umdh -pn:ProgramName -f:secondTraceFile.txt
D)
//
// Each log entry has the following syntax:
//
// + BYTES_DELTA (NEW_BYTES – OLD_BYTES) NEW_COUNT allocs BackTrace TRACEID
// + COUNT_DELTA (NEW_COUNT – OLD_COUNT) BackTrace TRACEID allocations
// … stack trace …
//
// where:
//
// BYTES_DELTA – increase in bytes between before and after log
// NEW_BYTES – bytes in after log
// OLD_BYTES – bytes in before log
// COUNT_DELTA – increase in allocations between before and after log
// NEW_COUNT – number of allocations in after log
// OLD_COUNT – number of allocations in before log
// TRACEID – decimal index of the stack trace in the trace database
// (can be used to search for allocation instances in the original
// UMDH logs).
//
2f70 ( 1fa0 – 4f10) 2 allocs BackTrace360
– 3 ( 2 – 5) BackTrace360 allocations
ntdll!RtlDebugAllocateHeap+000000E1
ntdll!RtlAllocateHeapSlowly+00000044
ntdll!RtlAllocateHeap+00000E64
MSVCRTD!_heap_alloc_base+0000013C (malloc.c, 200)
MSVCRTD!_heap_alloc_dbg+000001A2 (dbgheap.c, 378)
MSVCRTD!_nh_malloc_dbg+00000049 (dbgheap.c, 248)
MSVCRTD!_malloc_dbg+0000001F (dbgheap.c, 165)
MFC42D!operator new+00000024 (afxmem.cpp, 373)
MFC42D!operator new+00000016 (afxmem.cpp, 65)
te!CTeDlg::OnButton1+00000037 (E:testteDlg.cpp, 180)
MFC42D!_AfxDispatchCmdMsg+000000A2 (cmdtarg.cpp, 88)
MFC42D!CCmdTarget::OnCmdMsg+00000274 (cmdtarg.cpp, 302)
MFC42D!CDialog::OnCmdMsg+00000024 (dlgcore.cpp, 97)
MFC42D!CWnd::OnCommand+00000138 (wincore.cpp, 2099)
MFC42D!CWnd::OnWndMsg+00000053 (wincore.cpp, 1608)
MFC42D!CWnd::WindowProc+0000002E (wincore.cpp, 1596)
MFC42D!AfxCallWndProc+000000ED (wincore.cpp, 215)
通过以上线程调用栈可以很容易地查出引起内存泄漏的原因。
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!
0012f1d4 0012f2c8 0012f2dc 0012f200 7c9237bf
0012f1e4 0012f2c8 0012ffb0 0012f2dc 0012f29c
0012f1f4 0012f814 7c9237d8 0012ffb0 0012f2b0
0012f204 7c92378b 0012f2c8 0012ffb0 0012f2dc
0012f214 0012f29c 00402218 00000001 0012f2c8
0012f224 0012ffb0 7c957860 0012f2c8 0012ffb0
0012f234 0012f2dc 0012f29c 00402218 0012f600
0012f244 0012f2c8 00144c90 00230fd2 00000001
5.利用
eax=00000000 ebx=00000000 ecx=0012fe74 edx=00000000 esi=00144c90 edi=0012f600 eip=00401caf esp=0012f5a8 ebp=0012f600 iopl=0 nv up ei pl nz ac pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010216 JustTest!CJustTestDlg::OnButton1+0x2f: 00401caf f77df4 idiv eax,dword ptr [ebp-0Ch] ss:0023:0012f5f4=00000000 6.利用
二.死锁 有人说:多线程是万恶的根源。确实,在多线程编程中有两类 问题是不容易处理的。一:死锁,二:共享资源保护。 但是对于死锁,借助
. 0 Id: 1a04.109c Suspend: 1 Teb: 7ffdf000 Unfrozen ChildEBP RetAddr Args to Child 0012f510 7c92e9c0 7c93901b 00000780 00000000 ntdll!KiFastSystemCallRet 0012f514 7c93901b 00000780 00000000 00000000 ntdll!ZwWaitForSingleObject+0xc 0012f59c 7c92104b 00416868 0040237d 00416868 ntdll!RtlpWaitForCriticalSection+0x132 0012f5a4 0040237d 00416868 0012f8a0 00144c90 ntdll!RtlEnterCriticalSection+0x46 0012f600 5f4398cc 0012f8a0 00144c90 00000000 JustTest!CJustTestDlg::OnButton1+0x6d [D:testJustTestJustTestDlg.cpp @ 191] 1 Id: 1a04.1288 Suspend: 1 Teb: 7ffde000 Unfrozen ChildEBP RetAddr Args to Child 00d5fef0 7c92d85c 7c8023ed 00000000 00d5ff24 ntdll!KiFastSystemCallRet 00d5fef4 7c8023ed 00000000 00d5ff24 00d5ffb4 ntdll!NtDelayExecution+0xc 00d5ff4c 7c802451 00002710 00000000 00d5ffb4 kernel32!SleepEx+0x61 00d5ff5c 00401ca9 00002710 74680000 746800e0 kernel32!Sleep+0xf 00d5ffb4 7c80b50b 00000000 74680000 746800e0 JustTest!WndProc+0x39 [D:testJustTestJustTestDlg.cpp @ 179] 00d5ffec 00000000 00401087 00000000 00000000 kernel32!BaseThreadStart+0x37 该示例程序有两个活动线程,但是此时这个示例程序对于用户的任何操作均未响应,可以判断这个程序死锁了。 根据线程
—————————————– DebugInfo = 0x0014e8d8 Critical section = 0x00416868 (JustTest!g_cs+0x0) LOCKED LockCount = 0x1 OwningThread = 0x00001288 RecursionCount = 0x1 LockSemaphore = 0x780 SpinCount = 0x00000000 OwningThread DbgId = ~1s OwningThread Stack = ChildEBP RetAddr Args to Child 00d5fef0 7c92d85c 7c8023ed 00000000 00d5ff24 ntdll!KiFastSystemCallRet (FPO: [0,0,0]) 00d5fef4 7c8023ed 00000000 00d5ff24 00d5ffb4 ntdll!NtDelayExecution+0xc (FPO: [2,0,0]) 00d5ff4c 7c802451 00002710 00000000 00d5ffb4 kernel32!SleepEx+0x61 (FPO: [Non-Fpo]) 00d5ff5c 00401ca9 00002710 74680000 746800e0 kernel32!Sleep+0xf (FPO: [1,0,0]) 00d5ffb4 7c80b50b 00000000 74680000 746800e0 JustTest!WndProc+0x39 (CONV: stdcall) 00d5ffec 00000000 00401087 00000000 00000000 kernel32!BaseThreadStart+0x37 (FPO: [Non-Fpo]) 从以上命令执行结果分析,线程
THREAD 88d9a590 Cid 0c84.0f1c Teb: 7ffde000 Win32Thread: e4e858e8 WAIT: (WrUserRequest) UserMode Non-Alertable 8900b5a8 SynchronizationEvent Not impersonating DeviceMap e1713878 Owning Process 0 Image: Attached Process 88d9c8b0 Image: JustTest.exe Wait Start TickCount 204830 Ticks: 24996 (0:00:06:30.562) Context Switch Count 2836 LargeStack UserTime 00:00:00.046 KernelTime 00:00:00.046 Win32 Start Address 0x004020d0 Start Address 0x7c810867 Stack Init a98a1000 Current a98a0c20 Base a98a1000 Limit a989b000 Call 0 Priority 10 BasePriority 8 PriorityDecrement 0 DecrementCount 16 Kernel stack not resident. 综合以上内容分析 修改注册表使操作系统对每一次内存分配操作时的调用栈进行记录
umdh -pn:ProgramName -f:secondTraceFile.txt D) // // Each log entry has the following syntax: // // + BYTES_DELTA (NEW_BYTES – OLD_BYTES) NEW_COUNT allocs BackTrace TRACEID // + COUNT_DELTA (NEW_COUNT – OLD_COUNT) BackTrace TRACEID allocations // … stack trace … // // where: // // BYTES_DELTA – increase in bytes between before and after log // NEW_BYTES – bytes in after log // OLD_BYTES – bytes in before log // COUNT_DELTA – increase in allocations between before and after log // NEW_COUNT – number of allocations in after log // OLD_COUNT – number of allocations in before log // TRACEID – decimal index of the stack trace in the trace database // (can be used to search for allocation instances in the original // UMDH logs). // 2f70 ( 1fa0 – 4f10) 2 allocs BackTrace360 – 3 ( 2 – 5) BackTrace360 allocations ntdll!RtlDebugAllocateHeap+000000E1 ntdll!RtlAllocateHeapSlowly+00000044 ntdll!RtlAllocateHeap+00000E64 MSVCRTD!_heap_alloc_base+0000013C (malloc.c, 200) MSVCRTD!_heap_alloc_dbg+000001A2 (dbgheap.c, 378) MSVCRTD!_nh_malloc_dbg+00000049 (dbgheap.c, 248) MSVCRTD!_malloc_dbg+0000001F (dbgheap.c, 165) MFC42D!operator new+00000024 (afxmem.cpp, 373) MFC42D!operator new+00000016 (afxmem.cpp, 65) te!CTeDlg::OnButton1+00000037 (E:testteDlg.cpp, 180) MFC42D!_AfxDispatchCmdMsg+000000A2 (cmdtarg.cpp, 88) MFC42D!CCmdTarget::OnCmdMsg+00000274 (cmdtarg.cpp, 302) MFC42D!CDialog::OnCmdMsg+00000024 (dlgcore.cpp, 97) MFC42D!CWnd::OnCommand+00000138 (wincore.cpp, 2099) MFC42D!CWnd::OnWndMsg+00000053 (wincore.cpp, 1608) MFC42D!CWnd::WindowProc+0000002E (wincore.cpp, 1596) MFC42D!AfxCallWndProc+000000ED (wincore.cpp, 215) 通过以上线程调用栈可以很容易地查出引起内存泄漏的原因。 声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!