標籤:des style blog http color io os ar 使用
1. 解決線上.NET應用程式的如下問題:
2. 安裝WinDbg:
http://msdn.microsoft.com/en-us/windows/hardware/gg463009.aspx
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中http://www.microsoft.com/whdc/devtools/debugging/symbolpkg.mspx,下載相應作業系統所需要的完整的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中執行這段代碼:
[csharp] view plaincopyprint?
- 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:可以看到問題的所在。
異常如此重要,所以作業系統提供了對應的調試功能,可以使用調試器來檢視異常。異常發生後,作業系統在調用使用者態程式的異常處理函數前,會檢查目前使用者態程式是否有調試器載入。如果有,那麼作業系統會首先把異常資訊發送給調試器,讓調試器有觀察異常的第一次機會,所以也叫做first chance exception,調試器處理完畢後,作業系統才讓使用者態程式來處理。如果使用者態程式處理了這個異常,就沒調試器什麼事了。否則,程式在unhandled exception崩潰前,作業系統會給調試器第二次觀察異常的機會,所以也叫做second chance exception。
《Windows使用者態程式高效排錯》
分析以下代碼:可以看出DummyObject 會佔用很多記憶體,甚至導致記憶體溢出
[csharp] view plaincopyprint?
- 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
[csharp] view plaincopyprint?
- 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");
- }
[csharp] view plaincopyprint?
- private void HangProc(object obj)
- {
- lock (syncRoot) {
- n = 0;
- }
- }
CPU高
-如果與業務量沒有提升,有線程在長時間的處理
核心問題,找到佔用CPU的線程
!runaway
~*e!clrstack
線程死結出現的情況:
兩個鎖A,B,
一個線程已經拿到鎖A,申請鎖B,
另一個線程已經拿到鎖B,申請鎖A
核心問題:找到鎖定的線程
!threads
!syncblk
~*e!clrstack
•兩條指令可以解決大部分的問題•!dumpheap –stat•~*e!clrstack http://blog.csdn.net/kntao/article/details/7086616
使用Windbg調試.Net應用程式 [轉]