原文地址: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调试代码的方式比较陌生,还不够熟悉,可是仍是像最开始说的,只要稍微比较熟悉了,连蒙带差仍是能大致找处处问题的地方,精确找到问题,仍是须要进一步的学习。
本篇文章中,也许有不对的地方,若是发现,请指正,防止本身和你们之后出现一样的问题:)