1.使用windbg打开dump文件,同时设置symbols。
如果之前下载过windows的symbols就直接设置symbols path: (windows和程序的pdb)
例如:C:\Symbols;E:\work\技术分享\dump分析\1115服务器无响应dump\gsss\gssssvr
如果之前没有下载过windows的symbos则设置
C:\Symbols; SRV*e:\mylocalsymbols*http://msdl.microsoft.com/download/symbols;E:\work\技术分享\dump分析\1115服务器无响应dump\gsss\gssssvr
2.输入指令 ~*kv 输出所有的线程
3.找到异常的线程,例如下面的死锁(发现大部分函数都在等待临界区,死锁可能行非常大):
4.使用命令查看临界区信息: RtlEnterCriticalSection的第三个地址是045ab944(临界区地址), !cs Address 指定要显示的临界区地址。 : !cs 045ab944
5.切换到0x00004d0线程: ~~[0x00004d0]
执行 ~56s 切换到56号线程
6.输入kv,查看线程堆栈
7.标识对函数调用的线程 Kernel32! UnhandledExceptionFilter 。 它类似于以下
8.在第一个参数的指定位置显示内存内容 Kernel32! UnhandledExceptionFilter 通过 添加 第一个参数 。 此指向 EXCEPTION_POINTERS 结构
9.第一个 DWORD 代表异常记录。 若要获取有关异常的类型信息,请请在命令提示符处运行以下:.exr first DWORD from step 6
10.第二个 DWORD 是上下文记录。 若要获取上下文的信息,请在命令提示符处运行以下:.cxr second DWORD from step 6
11.运行 kv 命令获得实际的异常的调用堆栈
可以看到是json出现了问题,抛出了异常,但锁没有释放。
其他:
1.查看函数入参变量值
想要看到崩溃堆栈需要切换到上下文当中,用:.ecxr命令,然后在kp一下(kp表示打印堆栈并附带参数信息):
0:002> .ecxr
eax=00000000 ebx=00000000 ecx=61476f67 edx=ffffffff esi=61476f67 edi=7ffffffe
eip=7438d951 esp=001cc89c ebp=001ccd30 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202
msvcr120!_woutput_s_l+0x978:
7438d951 663901 cmp word ptr [ecx],ax ds:0023:61476f67=????
0:002> kp
*** Stack trace for last set context - .thread/.cxr resets it
ChildEBP RetAddr
001ccd30 7438d6a6 msvcr120!_woutput_s_l(struct _iobuf * stream = 0x001ccd54, wchar_t * format = 0x01912224 "--- memory read error at address 0x01912224 ---", struct localeinfo_struct * plocinfo = 0x00000000, char * argptr = 0x001ccde8 "???")+0x978 [f:\dd\vctools\crt\crtw32\stdio\output.c @ 1629]
001ccd74 7438e0e7 msvcr120!_vswprintf_helper( * woutfn = 0x7438d716, unsigned short * string = 0x003fe898, unsigned int count = 0x20c5, wchar_t * format = 0x019121e0 "--- memory read error at address 0x019121e0 ---", struct localeinfo_struct * plocinfo = 0x00000000, char * ap = 0x001ccdc8 "???")+0x8e [f:\dd\vctools\crt\crtw32\stdio\vswprint.c @ 157]
001ccd98 743a3600 msvcr120!_vswprintf_s_l(unsigned short * string = 0x003fe898, unsigned int sizeInWords = 0x20c5, wchar_t * format = 0x019121e0 "--- memory read error at address 0x019121e0 ---", struct localeinfo_struct * plocinfo = 0x00000000, char * ap = 0x001ccdc8 "???")+0x43 [f:\dd\vctools\crt\crtw32\stdio\vswprint.c @ 272]
001ccdb4 01219561 msvcr120!swprintf_s(unsigned short * string = 0x003fe898, unsigned int sizeInWords = 0x20c5, wchar_t * format = 0x019121e0 "--- memory read error at address 0x019121e0 ---")+0x17 [f:\dd\vctools\crt\crtw32\stdio\swprintf.c @ 243]
001cce2c 0120c7da wuxia!KSimpleLogger::writeLog(_LOG_LEVEL level = LOG_LEVEL_ERROR (0n2), wchar_t * log = 0x0040a008 "Muted failed, errorcode:255", int cch = 0n27)+0xd1 [d:\workspace\wuxiastreamer\libmisc\logger.cpp @ 321]
001ccf4c 7709abe6 wuxia!ksl_write_log(void * loggerObject = 0x0174599c, _LOG_LEVEL level = LOG_LEVEL_ERROR (0n2), wchar_t * format = 0x01745964 "--- memory read error at address 0x01745964 ---")+0x17a [d:\workspace\wuxiastreamer\libmisc\simple_logger.cpp @ 127]
001ccf64 5119097c user32!CallNextHookEx+0x48
WARNING: Stack unwind information not available. Following frames may be wrong.
001cd010 76f76aee Qt5Core+0x1b097c
001cd0f4 7709e171 ntdll!KiUserCallbackDispatcher+0x2e
001cd170 770ac560 user32!CallHookWithSEH+0x21
001cd204 770acc40 user32!UserCallWinProcCheckWow+0x5c
001cd214 51190613 user32!DispatchMessageW+0xf
001cd21c 7f8eee35 Qt5Core+0x1b0613
001cd244 00000000 0x7f8eee35
2.查看局部变量
我们可以转到这行堆栈,然后看看里面的细节:
先用kn (表示第一列显示显示堆栈列号)
0:002> kn
*** Stack trace for last set context - .thread/.cxr resets it
# ChildEBP RetAddr
00 001ccd30 7438d6a6 msvcr120!_woutput_s_l+0x978 [f:\dd\vctools\crt\crtw32\stdio\output.c @ 1629]
01 001ccd74 7438e0e7 msvcr120!_vswprintf_helper+0x8e [f:\dd\vctools\crt\crtw32\stdio\vswprint.c @ 157]
02 001ccd98 743a3600 msvcr120!_vswprintf_s_l+0x43 [f:\dd\vctools\crt\crtw32\stdio\vswprint.c @ 272]
03 001ccdb4 01219561 msvcr120!swprintf_s+0x17 [f:\dd\vctools\crt\crtw32\stdio\swprintf.c @ 243]
04 001cce2c 0120c7da wuxia!KSimpleLogger::writeLog+0xd1 [d:\workspace\wuxiastreamer\libmisc\logger.cpp @ 321]
05 001ccf4c 7709abe6 wuxia!ksl_write_log+0x17a [d:\workspace\wuxiastreamer\libmisc\simple_logger.cpp @ 127]
06 001ccf64 5119097c user32!CallNextHookEx+0x48
WARNING: Stack unwind information not available. Following frames may be wrong.
07 001cd010 76f76aee Qt5Core+0x1b097c
08 001cd0f4 7709e171 ntdll!KiUserCallbackDispatcher+0x2e
09 001cd170 770ac560 user32!CallHookWithSEH+0x21
0a 001cd204 770acc40 user32!UserCallWinProcCheckWow+0x5c
好,转到wuxia!KSimpleLogger::writeLog这行堆栈用:.frame 4 (如果想转到下一行用 :.frame 5)
0:002> .frame 4
04 001cce2c 0120c7da wuxia!KSimpleLogger::writeLog+0xd1 [d:\workspace\wuxiastreamer\libmisc\logger.cpp @ 321]
然后可以用:dv来打印临时变量信息:
0:002> dv
Unable to find processor type for C:\Program Files\wuxia\1.0.0.13\wuxia.exe, using default
this = 0x61476f67
level = LOG_LEVEL_ERROR (0n2)
log = 0x0040a008 "Muted failed, errorcode:255"
cch = 0n27
st = struct _SYSTEMTIME
dwWritten = 0x174599c
查看局部成员指针变量 : dt datatype ptraddr
查看CString类型的值 dc 变量名 + dt CString addr
参考:https://blog.csdn.net/liaozhilong88/article/details/80591792