1. 解决线上.NET应用程序的如下问题:
- 崩溃
- CPU高
- 程序异常
- 程序Hang死
2. 安装WinDbg:
3. 配置WinDbg:
运行WinDbg->菜单->File->Symbol File Path->按照下面的方法设置_NT_SYMBOL_PATH变量:在弹出的框中输入“C:\MyCodesSymbols; SRV*C:\MyLocalSymbols*http://msdl.microsoft.com/download/symbols”(按照这样设置,WinDbg将先从本地文件夹C:\MyCodesSymbols中查找Symbol,如果找不到,则自动从MS的Symbol Server上下载Symbols)。另一种做法是从这个Symbol下载地址中,下载相应操作系统所需要的完整的Symbol安装包,并进行安装,
4. 利用WinDbg里的adplus来获取dump文件。
Dump文件是进程的。可以把程序的执行状态通过调试器保存到dump文件中。
在WinDbg安装目录里可以找到adplus.exe,把他拖入到命令行中,然后用命令
adplus.exe -hang -pn test.exe -o c:\dumps // 抓取当前的dump文件
adplus.exe -crash -pn test.exe -o c:\dumps // 监听应用程序,当crash时,获取dump文件
命令-pn :应用程序名,-p:应用程序pid,-odump文件输出路径
5. 利用WinDbg加载dump文件加载调试器
运行WinDbg->菜单->File->Open Cresh dump 打开dump文件,并加载.net调试器
.loadby sos mscorwks .Net 3.5版本及以下
.loadby sos clr .Net 4.0
如果服务器的.Net版本与本机不匹配需要服务器版本的mscordacwks.dll文件
并设置.sympath = mscordacwks_x86_x86_2.0.50727.3607.dl
6. WinDbg的基本命令
help sos指令帮助
!threads 显示所有线程
!dumpheap 显示托管堆的信息
!clrstack 显示调用栈
!dumpobj 显示一个对象的内容
!dumparray 显示数组
!syncblk 显示同步块
!runaway 显示线程cpu时间
!gcroot 跟踪对象内存引用
!pe 打印异常
7. WinDbg的使用
当我在Form中执行这段代码:
public Form1(){ InitializeComponent(); AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); } private void UnhandledExceptionProc(object obj){ try { throw new Exception("1st chance"); } catch (Exception) { MessageBox.Show("after 1st"); } int d = 0; int n = 1 / d; }并活动dump文件
用windbg打开dump文件后输入-pe:可以看到问题的所在。《Windows用户态程序高效排错》
分析以下代码:可以看出DummyObject 会占用很多内存,甚至导致内存溢出
private void MemeryLeakProc(object obj) { while (true) { for (int i = 0; i < 100 * 1024; i++) { DummyObject o = new DummyObject(); list.Add(o); } Thread.Sleep(1000); } }windbg命令:!dumpheap –stat 统计堆栈内存
线程Hang住的常见原因
核心问题,找到被hang住的线程
!threads
~*e!clrstack
!synblk
lock (syncRoot) { int tp; int io; //ThreadPool.GetMaxThreads(out tp, out io); for (int i = 0; i < 100; i++) { Thread hangThread = new Thread(HangProc); hangThread.Start(); } MessageBox.Show("Press to release lock"); } private void HangProc(object obj) { lock (syncRoot) { n = 0; } }CPU高
核心问题,找到占用CPU的线程
!runaway
~*e!clrstack
线程死锁出现的情况:
两个锁A,B,
一个线程已经拿到锁A,申请锁B,
另一个线程已经拿到锁B,申请锁A
核心问题:找到锁定的线程
!threads
!syncblk
~*e!clrstack