俗话说:万事开头难!html
自历来到新公司遇到性能问题后,须要想办法解决这个问题,可是一直没有合适的性能分析工具,而后找到StevenChennet 大神帮忙,他用WinDbg工具远程帮我分析了一个 dump文件,可是只看到键盘 “啪啪啪”,获得告终果,却不是很清楚WinDbg神奇具体如何使用的。结果,次日,性能问题又来了,总不能每次劳烦大神驾到,因此不得不本身开始学习WinDbg,这里记录一个入门过程。windows
从下面的地址打开:
https://msdn.microsoft.com/en-us/windows/hardware/hh852365
而后看到
Standalone Debugging Tools for Windows (WinDbg)
下载。
安装好后,在开始-》Windows Kits文件夹下有 WinDbg(x86),WinDbg(x64) 两个程序的快捷方式,若是你要调试
64位的程序,就用WinDbg(x64)。sass
能够在任务管理器,进程-》建立转储文件 里面,获得当前进程的dump文件,我是用下面这个程序来生成转储文件的:
Procdump
下载地址:https://technet.microsoft.com/en-us/sysinternals/dd996900.aspx
有关 ProDump程序的使用,能够参考下面2个博客文章:
High CPU Dump收集工具 - ProcDump使用方法服务器
在命令行,运行这个程序:工具
procdump -ma mydotNetApp.exe d:\myapp.dmp
运行后,将获得一个myapp.dmp 文件,若是这个文件是在本机生成的,那么VS2013能够直接打开这个文件并能够分析托管内存,可是,每每内存转储文件是 在服务器生成的,而服务器又极可能跟开发环境不同,因此才须要本文介绍的 WinDbg来调试。oop
首先,打开咱们刚才的转储文件,可使用菜单命令打开:
File->Open Crash Dump...
打开后,会显示程序当时运行所在的环境,此时,会提示符号文件没有发现:性能
*** ERROR: Symbol file could not be found. Defaulted to export symbols for ntdll.dll -
若是不配置,使用命令的时候会提示错误,好比:学习
0:000> .loadby sos clrjit 0:000> !tp *** ERROR: Symbol file could not be found. Defaulted to export symbols for clr.dll - ************* Symbol Loading Error Summary ************** Module name Error clr PDB not found : e:\appserver\symbols\dll\clr.pdb
e:\appserver 是个人dmp文件所在的目录,它默认是到symbols 子目录去找符号文件去了。spa
而后,配置下使用此文件的调试环境。
在菜单命令 File->Symbol path... 打开对话框,选择浏览,找到dmp文件所在目录相关的程序文件目录 E:\AppServer ,该目录下面有程序相关的 exe,pdb 文件。
输入下面的命令:
0:000> .sympath+ c:\symbols Symbol search path is: E:\AppServer;c:\symbols Expanded Symbol search path is: e:\appserver;c:\symbols Error: Attempts to access 'c:\symbols' failed: 0x2 - 系统找不到指定的文件。 ************* Symbol Path validation summary ************** Response Time (ms) Location OK E:\AppServer Error
这里不用管,这个文件夹后面能够生成。
0:000> .symfix 0:000> .symfix+ c:\symbols 0:000> .sympath Symbol search path is: srv* Expanded Symbol search path is: SRV*c:\symbols*http://msdl.microsoft.com/download/symbols ************* Symbol Path validation summary ************** Response Time (ms) Location Deferred
这下对了。
执行下 reload命令:
0:000> .reload ................................................................ ................................................................ ............
接着执行下面:
0:000> .loadby sos clr 0:000> !tp The version of SOS does not match the version of CLR you are debugging. Please load the matching version of SOS for the version of CLR you are debugging. CLR Version: 4.0.30319.296 SOS Version: 4.6.96.0 Failed to load data access DLL, 0x80004005
这里提示说SOS的版本更CLR不匹配,这里须要找到当时生成Dump文件所在的服务器上的 sos.dll,注意,由于服务器程序是64位的,因此必须在 .Net Framework64 目录去找,同时把 mscordacwks.dll 文件一块儿拷贝过来(先暂时不用,下面立刻会讲到)。
刚才这个命令执行后,咱们惊喜的发现,c:\symbols 目录本身建立了,而且下载了 clr.pdb等几个目录,这是再将刚才服务器上拷贝的 sos.dll, mscordacwks.dll ,放到本地机器的 c:\symbols 目录下面。
再次执行这几个命令:
0:000> .reload ................................................................ ................................................................ ............ 0:000> .loadby sos clr 0:000> !tp The version of SOS does not match the version of CLR you are debugging. Please load the matching version of SOS for the version of CLR you are debugging. CLR Version: 4.0.30319.296 SOS Version: 4.6.96.0 Failed to load data access DLL, 0x80004005
仍是报错,看来 sos.dll 没有加载正确,用下面的命令:
0:000> .load c:\symbols\sos.dll 0:000> .loadby sos clr 0:000> !tp
这里load命令必须带SOS.dll的路径。加载了它,而后执行 .loadby sos clr ,表示调试.NET托管程序。
开始漫长的等待,程序窗口提示:
*BUSY*
Downloading symbols for [clr.pdb] /
等到相关的符号文件所有下载完毕,终于出现了久违的成功界面:
CPU utilization: 11% Worker Thread: Total: 8 Running: 0 Idle: 8 MaxLimit: 32767 MinLimit: 8 Work Request in Queue: 0 -------------------------------------- Number of Timers: 14 -------------------------------------- Completion Port Thread:Total: 1 Free: 1 MaxFree: 16 CurrentLimit: 0 MaxLimit: 1000 MinLimit: 8
有关WinDbg详细的调试命名,能够参考下面文章:
windbg调试命令
http://www.cnblogs.com/kekec/archive/2012/12/02/2798020.html
或者,你也能够随时用帮助,查看如何使用:
0:000> !help ------------------------------------------------------------------------------- SOS is a debugger extension DLL designed to aid in the debugging of managed programs. Functions are listed by category, then roughly in order of importance. Shortcut names for popular functions are listed in parenthesis. Type "!help <functionname>" for detailed info on that function. Object Inspection Examining code and stacks ----------------------------- ----------------------------- DumpObj (do) Threads DumpArray (da) ThreadState DumpStackObjects (dso) IP2MD DumpHeap U DumpVC DumpStack GCRoot EEStack ObjSize CLRStack FinalizeQueue GCInfo PrintException (pe) EHInfo TraverseHeap BPMD COMState Examining CLR data structures Diagnostic Utilities ----------------------------- ----------------------------- DumpDomain VerifyHeap EEHeap VerifyObj Name2EE FindRoots SyncBlk HeapStat DumpMT GCWhere DumpClass ListNearObj (lno) DumpMD GCHandles Token2EE GCHandleLeaks EEVersion FinalizeQueue (fq) DumpModule FindAppDomain ThreadPool SaveModule DumpAssembly ProcInfo DumpSigElem StopOnException (soe) DumpRuntimeTypes DumpLog DumpSig VMMap RCWCleanupList VMStat DumpIL MinidumpMode AnalyzeOOM (ao) Examining the GC history Other ----------------------------- ----------------------------- HistInit FAQ HistRoot HistObj HistObjFind HistClear
也可使用 .help命令,这个不同,这里列出部分命令:
0:000> .help . commands: .allow_exec_cmds [0|1] - control execution commands .allow_image_mapping [0|1] - control on-demand image file mapping .apply_dbp [<options>] - add current data breakpoint state to a register context .asm [<options>] - set disassembly options .asm- [<options>] - clear disassembly options .attach <proc> - attach to <proc> at next execution .block { <commands> } - brackets a set of commands for nested execution .break - break out of the enclosing loop
也可以使用.hh命令:
Use ".hh <command>" or open debugger.chm in the debuggers directory to get
detailed documentation on a command.
OK,有了dump文件生成,调试环境配置,还有帮助命令,如今总算是入门了。