原文地址:html
http://www.cnblogs.com/Lawson/archive/2011/01/23/1942692.htmlweb
很早看到windbg+sos方面的知識,一直沒仔細學習,也許由於本身作的系統還不夠複雜,也沒線上真實環境查看的權限,一直沒學習這方面的知識,最近幾天仔細找了這方面的資料,本身也寫了個可能形成高CPU高內存的測試web頁面,發現確實不錯,即便一個生手,也能夠用工具連蒙帶騙的猜出哪裏出了問題,固然對一些命令和內部標示更熟悉了後,能夠更好的找出問題所在,很是值得學習。我在使用過程當中,也遇到大量問題,好比系統兼容,軟件版本,.net版本等,部分我也沒能理解清楚,但如今確實用它找到了程序的問題,所以做個記錄,爲之後本身或你們查閱資料提供必定的方便。windows
基本工做:框架
我用的windbg是6.11.1.404的32位版本,微軟官網下載地址:http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx#b,SOS是每一個.net框架都自帶的,我用的.net4.0的sos.dll,個人在C:\Windows\Microsoft.NET\Framework\v4.0.30319裏面,另外我還用了調式的pdb符號文件,若是不下載,能夠配置須要的時候自動下載,但下載須要選擇操做系統版本。windbg老版本使用過程當中報過mscorlib的什麼錯誤,具體記不起了,但之前別人用起過,我確實用不起,換新版本就行了。dom
配置工做及經常使用命令:工具
在windbg主窗口點擊File下面的Symbol Search Path,設置符號文件路徑,好比個人:C:\Windows\symbols\dll;srv*C:\symbols*http://msdl.microsoft.com/download/symbols,其實C:\symbols纔是我下載的符號文件安裝位置,http://msdl.microsoft.com/download/symbols這個是必須的,由於找不到符號文件,它會自動從這裏下載。也能夠從註冊表設置,但我沒在註冊表設置它。學習
我在調試過程當中windbg界面以下:測試
通常咱們找到程序出問題大致的地方,能夠直接查看對應代碼,若是沒源代碼,咱們一樣能夠用windbg導出指定程序集地址的代碼,而後反編譯看到源代碼,尤爲好比部分dll文件是其餘團隊的代碼,咱們看不到的時候。spa
經常使用命令好比:操作系統
第一步通常是.load C:\Windows\Microsoft.NET\Framework\v4.0.30319\SOS.dll,加載sos,這樣才能調試託管代碼
查看引發CPU太高命令好比:
!threadpool,查看線程池CPU使用量,我認爲WEB的好比iis應用程序池進程w3wp若是CPU使用太高,那查看線程池命令確定看的出來太高,這個是我本身的理解,c/s的就不必定了。
!runaway,查看線程佔用CPU時間,能夠從中找到哪一個線程佔用時間更高。
~number s,number爲具體哪一個線程的ID。
!clrstack,到具體某個線程後,查看當前線程的託管代碼
!name2ee ,找到哪一個託管代碼模塊後,查看MethodTable,EEClass等信息。
!dumpmt,找到相關MethodTable處的相關信息。
!dumpmd,根據MethodDesc找到相關模塊信息,好比MethodTable.
!dumpdomain,顯示全部域裏的程序集,或者根據參數獲取指定域。
!savemodule,根據具體程序集地址,把當前程序集的代碼生成到指定文件
查看佔用內存太高的命令好比:
!eeheap,查看堆中信息,能夠查看到大對象。
!dumpheap,查看堆中信息,通常帶-min,-stat,-type等參數。
!gcroot,根據堆地址,查看相關模塊引用代碼信息。
其餘命令固然還很是多,也很是有用,須要的時候再翻資料,若是須要很精通windbg+sos,仍是老老實實仔細看吧。
開始調試:
通常分析dump文件方式,能夠直接附加進程分析,也能夠保存dump文件,再單獨線下分析。 在線調試,直接Attach to a process就能夠了,通常線下調試,能夠用windbg的
adplus.vbs生成dump文件,命令以下:adplus -hang -o d:\dump -p 1234,其中hang表示附加到進程,若是是—crash,則爲目標進程崩潰的時候抓取,-o後面的參數表示dump文件放到說明位置,-p後面的數字爲進程的PID,也能夠是-pn後面跟進程名稱。在個人使用過程當中,win7的系統,用adplus抓取w3wp進程老失敗,抓其餘普通進程沒問題,最終我用windows任務管理器查看到的進程界面,點擊w3wp進程,右鍵建立轉儲文件,它自動生成的dmp的dump文件到臨時目錄,這裏它建立的dump文件大小將遠遠大於當前進程的實際大小。
個人測試程序在VS2010下的MVC2代碼以下:模擬常見的程序形成循環過大,靜態事件綁定到實例對象,形成不釋放內存等會引發CPU過大,內存太高的問題。
訪問/home/index後,形成我CPU立刻升到50%左右,內存倒看不出來,但多個訪問後會有沒法釋放的內存愈來愈大。
首先載入sos後,下面是個人命令記錄:(.........爲省略更多內容,因爲我記錄的時候線程已經切換到25了,顯示0:025>了)
0:025> !threadpool
CPU utilization: 51%
...................
查看什麼線程佔用CPU多一點
0:025> !runaway
User Mode Time
Thread Time
25:920 0 days 0:00:03.042
0:150c 0 days 0:00:00.046
9:6c 0 days 0:00:00.015
27:1598 0 days 0:00:00.000
26:15cc 0 days 0:00:00.000
24:1084 0 days 0:00:00.000
切換到25線程:
0:025> ~25s
eax=2362d4fc ebx=00000000 ecx=00000001 edx=00000000 esi=01c9e838 edi=01ca4934
eip=00d70746 esp=0e2dee44 ebp=0e2dee58 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
00d70746 8bd9 mov ebx,ecx
查看託管代碼:
0:025> !clrstack
OS Thread Id: 0x920 (25)
Child SP IP Call Site
0e2dee44 00d70746 DumpWebTests.Controllers.HomeController.MyMethod()
0e2dee60 00d70580 DumpWebTests.Controllers.HomeController.Index()
...............................
0:025> !name2ee * DumpWebTests.Controllers.HomeController
Module: 64bd1000
Assembly: SMDiagnostics.dll
................
Module: 008b689c
Assembly: DumpWebTests.dll
Token: 02000004
MethodTable: 0130002c
EEClass: 00c84348
Name: DumpWebTests.Controllers.HomeController
查看模塊信息:
0:025> !dumpmt 0130002c
EEClass: 00c84348
Module: 008b689c
Name: DumpWebTests.Controllers.HomeController
mdToken: 02000004
File: C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\9f8ccc72\b9d96a8\assembly\dl3\9b2cfeec\916cd56e_eebacb01\DumpWebTests.dll
BaseSize: 0x38
ComponentSize: 0x0
Slots in VTable: 45
Number of IFaces in IFaceMap: 6
查看全部程序集:
0:025> !dumpdomain
查看到下面的信息:
Module Name
008b689c C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\9f8ccc72\b9d96a8\assembly\dl3\9b2cfeec\916cd56e_eebacb01\DumpWebTests.dll
Assembly: 00e4b2c8 [C:\Windows\assembly\GAC_MSIL\System.Web.Mvc\2.0.0.0__31bf3856ad364e35\System.Web.Mvc.dll]
ClassLoader: 00e234f8
SecurityDescriptor: 00e82280
保存程序集:
0:025> !savemodule 008b689c d:\dump\out.dll
3 sections in file
section 0 - VA=2000, VASize=39c4, FileAddr=200, FileSize=3a00
section 1 - VA=6000, VASize=320, FileAddr=3c00, FileSize=400
section 2 - VA=8000, VASize=c, FileAddr=4000, FileSize=200
已經把分析出的有問題的程序dll保存到d盤dump目錄的Out.dll文件了,若是有源代碼,固然能夠直接查看對應方法的代碼,這個就把CPU太高的程序找到了,具體緣由固然還要本身分析代碼了,
分析內存太高的方法,前面的經常使用方法裏按照步驟就能找到了,這裏就不寫到博文裏了。
其實我也還對windbg+sos調試代碼的方式比較陌生,還不夠熟悉,可是仍是像最開始說的,只要稍微比較熟悉了,連蒙帶差仍是能大致找處處問題的地方,精確找到問題,仍是須要進一步的學習。
本篇文章中,也許有不對的地方,若是發現,請指正,防止本身和你們之後出現一樣的問題:)