如何调试尖峰ASP.NET进程的内存转储?

时间:2008-10-07 14:38:49

标签: asp.net .net debugging windbg

抱歉,我无法想出一个很好的方式来表达我的真实问题。

我在64位计算机上运行高流量的ASP.NET站点。我有IIS以32位模式运行,但由于应用程序的一些遗留组件。我正在一个应用程序池中运行这个特定的Web应用程序,该应用程序池中有web园选项(在8核机器内运行6个进程)。

每周一到两次,其中一个进程将飙升至100%的CPU利用率,导致网站出现大幅减速,因此我的计划是等到发生这种情况,内存转储有问题的进程,然后将WinDbg调到零在看到代码旋转轮子的位置上的线程。

我之前使用WinDbg进行了调试,找出导致网站死机的原因,但那是几个月前,我不记得我是如何工作的。 (作为旁注,这是记录你所做的一切的教训。)

我正在运行该站点的Windows 2003服务器上运行WinDbg,以防止任何DLL版本问题。到目前为止,这是我的步骤,请告诉我出错的地方,以获取我收到的错误消息。

  1. 我首先使用UserDump使用以下命令转储spiking进程,其中3389是进程的ID:

    userdump -k 3389

  2. 我将转储加载到WinDbg的x86版本中。

  3. 由于我在64位计算机上运行32位,我首先加载内存转储然后:

    .load wow64exts

    .effmach x86

  4. 我确保我的符号路径包含包含我的应用PDB文件的目录:

    .sympath+ c:\inetpub\myapp\bin

  5. 只运行`.load SOS'失败并显示错误“系统无法找到指定的文件”,所以我选择了以下的完全限定路由,这有效:

    .load c:\windows\microsoft.net\framework\v2.0.50727\sos

  6. 从这里开始,我迷路了。我尝试任何一个SOS命令,如!threads,只是为了得到这个错误:

    Failed to load data access DLL, 0x80004005
    

    该错误还伴随着我应该验证的编号项目列表。  我已经验证我正在运行最新版本的调试器,mscordacwks.dll实际上与mscorwks.dll文件位于同一目录中,并且我在与转储文件相同的架构上进行调试。

    我还运行了神奇的“.cordll -ve -u -l”命令,但这并没有解决任何问题。当我执行时,我总是受到“CLR DLL status: No load attempts”的欢迎。然后我尝试“.reload”,这会产生一些警告,例如“WARNING: wldap32 overlaps dnsapi”。我希望它说“CLRDLL: Loaded DLL C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscordacwks.dll”之类的东西。但事实并非如此。

5 个答案:

答案 0 :(得分:3)

在运行sos命令之前尝试执行!sw。请参阅此blog post

答案 1 :(得分:2)

答案 2 :(得分:2)

根据我的经验,尖峰应用程序池可能是由于它被回收。您是否尝试过IIS崩溃/挂起代理和IIS转储?

http://www.microsoft.com/downloads/details.aspx?FamilyID=01c4f89d-cc68-42ba-98d2-0c580437efcf&DisplayLang=en

它们还包含一个dumpfile分析器,它将告诉您内存泄漏,甚至建议您需要修复的代码区域(包括指向适用的MSKB文章的链接!)

答案 3 :(得分:1)

老兄 - 不确定这是否有帮助,但也许可以尝试一下。

  1. 将c:\ windows \ microsoft.net \ framework \ v2.0.50727 \ sos.dll复制到安装windbg的同一目录(例如,c:\ program files \ Windows调试工具\)。为什么?使加载sos文件变得容易
  2. run windbg
  3. 加载内存转储文件。对我来说,我使用ctrl-D或文件 - >打开崩溃转储
  4. .load sos< - 在加载命令
  5. 之前记下fullstop
  6. .symfix c:\ temp \ debug_symbols
  7. .reload
  8. 好的..注意命令行。这告诉我转储所在的当前THREAD。这对于高CPU场景来说可能没用..因为我们可以在任何线程中。

    所以从这里我看看正在运行的线程并查看最繁忙的线程

    8!threadpool< - 这样我就可以看到cpu利用率来检查我们处于废话(繁忙)状态......例如100%cpu或者什么不是。

    9!runaway< - 列出最长的ben ... 例如

    0:027 !runaway
    User Mode Time
    Thread       Time
    18:704       0 days 0:00:17.843   <-- Thread #18
    19:9f4       0 days 0:00:13.328   <-- Thread #19
    16:1948      0 days 0:00:10.718
    26:a7c       0 days 0:00:01.375
    24:114       0 days 0:00:01.093
    27:d54       0 days 0:00:00.390
    28:1b70      0 days 0:00:00.328
    0:b7c       0 days 0:00:00.171
    25:3f8       0 days 0:00:00.000
    23:1968      0 days 0:00:00.000
    
    线程18和19已经悬挂了一段时间..嗯....它们是否陷入了循环?

    1. ~18s&lt; - goto thread 18。
    2. !clrstack&lt; - clr call stack ..就像在windows中调试一样。
    3. ..从这里你可以通过提供地址引用和东西来转储对象和东西。

      退房!帮助列出一些尝试使用的命令..我认为!help.sos也有效吗?

      HTH ..如果你仍然被困住,请询问哪些有效,哪些无效。

答案 4 :(得分:1)

我只需处理类似的问题。在我的情况下,事实证明WinDbg无法找到正确版本的mscorwks.dll。除了Framework版本之外,还有一个DLL的修订版,它可以在同一框架版本之间有所不同。

理论上,Microsoft符号服务器应该能够提供必要的DLL,但它并没有发生在我身上。为了解决这个问题,我使用!sym noisy来获取有关符号加载的其他信息。当我!dumpstack时,我收到了错误消息:

SYMSRV: http://msdl.microsoft.com/download/symbols/mscorwks.dll/492B82C1590000/mscorwks.dll not found

为了解决这个问题,我在本地符号缓存中创建了相应的文件夹,并从转储来自的机器上复制了mscorwks.dll。在.reload之后,WinDbg在本地符号缓存中找到了必要的DLL,并继续愉快地继续。

或者,您可以找到与lm v m mscorwks一起使用的mscorwks的确切版本。然后,您可以从this list中找到包含所需版本的更新。您需要从特定更新中提取必要的DLL到正确的位置。