利用 windbg 分析崩溃、句柄泄漏、死锁、CPU 高、内存泄漏 Windbg 的一些简单使用命令
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug
Debugger "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe" -p %ld -e %ld -g
Auto 1
| uf ICSF!SfDirectoryControl | 可以查看整个函数的汇编代码 |
| u ICSF!SfDirectoryControl ICSF!SfDirectoryControl+0x30 | 可以看到 30 个字节的汇编指令 |
| ub ICSF!SfDirectoryControl L30 | 可以查看 SfDirectoryControl 之上的 30 字节的汇编指令 |
CONTEXT: (.ecxr)
eax=0041f8fc ebx=013b0000 ecx=0041f924 edx=013b0000 esi=02ea1b04 edi=03004624
eip=013e4a38 esp=0041f6d4 ebp=fffffde0 iopl=0 nv up ei ng nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010282
fastapp!KzPath::GetModuleFolder+0x38:
013e4a38 89bde0fdffff mov dword ptr [ebp-220h],edi ss:002b:fffffbc0=????????
Resetting default scope
EXCEPTION_RECORD: (.exr -1)
ExceptionAddress: 013e4a38 (fastapp!KzPath::GetModuleFolder+0x00000038)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000001
Parameter[1]: fffffbc0
Attempt to write to address fffffbc0
0:000> u 00274a38
fastapp!KzPath::GetModuleFolder+0x38 [D:\PCGMR_BUILD\Cim\CiSrc\zapp\zapp\include\framework\KzPath.cpp @ 52]:
00274a38 89bde0fdffff mov dword ptr [ebp-220h],edi
00274a3e c785dcfdffff00000000 mov dword ptr [ebp-224h],0
00274a48 c745fc01000000 mov dword ptr [ebp-4],1
00274a4f e89cbefeff call fastapp!ATL::CAtlStringMgr::GetInstance (002608f0)
00274a54 8bc8 mov ecx,eax
00274a56 85c9 test ecx,ecx
00274a58 0f84b9000000 je fastapp!KzPath::GetModuleFolder+0x117 (00274b17)
00274a5e 8b01 mov eax,dword ptr [ecx]
0:000> ln 00274a38
D:\PCGMR_BUILD\Cim\CiSrc\zapp\zapp\include\framework\KzPath.cpp(52)+0x38
(00274a00) fastapp!KzPath::GetModuleFolder+0x38 | (00274b30) fastapp!KzPath::LegalizePath
.ecxr; kbn 得到崩溃的堆栈
.frame 0 ,切到第 0 帧如下dv 查看当前帧的一些变量信息
!htrace -enable 命令开启句柄检测!htrace –snapshot!htrace –diff
lsa handleLeak!ThreadProc1+0x00000037
补充:
可以在 windbg 调式中,输入 !handle 可以得到当前堆栈的一些句柄信息,可以看出这个堆栈 event 非常多。
~*kv ,输出所有线程!find stackntdll!RtlEnterCriticalSection ,查找哪些线程在等待锁
ThreadProc1 lock g_mutex2; 没发生,怀疑是否死锁了!cs 00bf7140 ,查看这把锁信息
~~[0x00002cc4] ,发现对应是 3 号线程
至此分析完成 2 号线程和 3 号线程发生死锁。
!runawaycpuhigh!ThreadProc1+0x35
!heap –s!heap–s
!heap -stat -h00970000 ,查看这个堆状态
!heap -flt s 224 ,查看 224 这些块被谁在使用!heap -p -a 00971d20 ,查看堆栈lsa memoryleak!ThreadProc1+0x00000048
gflags.exe /i memoryleak.exe +ustSET _NT_SYMBOL_PATH=SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols;F:\windbgtest\Debug
umdh-pn:memoryleak.exe -f:memory1.logumdh -pn:memoryleak.exe -f:memory2.logumdh -dmemory1.log memory2.log -f:memoryleak.log
WinDbg 的 !heap 命令非常强大,结合 AppVerifier 可以对堆 (heap) 内存进行详细的跟踪和分析
用户态栈默认大小为 1MB,默认内核态栈大小为: 在 x86 系统中,内核栈的初始大小是 12KB,在 X64 CPU(intel 64 和 AMD 64)的系统中,内核态栈的初始大小是 24KB,在安腾(Itanium)处理器的系统中,内核态栈的大小是 32KB。
!address
!address -summary
!address -Stack # 用于线程堆栈的内存。
并发堆栈,首先我们需要知道有多少线程。
~* :查看所有线程~.kp :查看当前线程调用堆栈~*kp :查看所有线程调用堆栈利用 windbg 分析崩溃、句柄泄漏、死锁、CPU 高、内存泄漏 Windbg 的一些简单使用命令