[ASP.NET Debugging BuggyBits读书笔记] Lab05 Crash

1. 在WinDbg目录执行 adplus –crash –pn w3wp.exe –quiet

2. 在 IIS manager里面浏览 CompanyInformation.aspx 页面,在文本框内输入字符串,点击send。此时浏览器将尝试将得不到响应,最后出现空白页面,表明IIS进程crash了。

3. 观察生成的dump,发现只有一个first change的mini dump,没有full dump,没有second-chance的dump。这表明程序在第一次出现exception的时候就crash掉了,可能是一些比较严重的问题,比如heap corruption或者stack overflow。

4. 为了使用adplus能够抓到first chance的full dump,我们需要引入adplus的config文件。在重新浏览CompanyInformation页面以后,在WinDbg目录执行以下命令 adplus –pn w3wp.exe –c c:\crash.cfg

crash.cfg的内容为:

<ADPlus> 
    <Breakpoints> 
      <NewBP> 
          <Address> Kernel32!ExitProcess </Address> 
          <Type> BP </Type> 
       </NewBP>  
       <NewBP> 
          <Address> Kernel32!TerminateProcess </Address> 
          <Type> BP </Type> 
       </NewBP> 
       <Config> 
          <Address> AllBreakpoints </Address> 
          <Actions> FullDump  </Actions> 
          <ReturnAction> QD </ReturnAction> 
       </Config>  
    </Breakpoints> 
    <Exceptions>

         <Config> 
           <Code> AllExceptions </Code> 
           <Actions1>  void </Actions1> 
           <Actions2> Log;Stack </Actions2>       
         </Config> 
         <Config> 
           <Code> AV </Code> 
           <Actions1>  Minidump </Actions1> 
         </Config> 
  </Exceptions> 
</ADPlus>   

5. 再次reproduce问题以后,抓到的first chance的crash dump的如下:

image

6. 使用WinDbg打开dump文件,载入SOS,执行 !clrstack

[ASP.NET Debugging BuggyBits读书笔记] Lab05 Crash_第1张图片

可见程序是反复执行了Utility.WriteToLog方法和ExceptionHandler方法,最终导致栈溢出。

7. 查找程序源代码,在ExceptionHandler.cs这个文件里面找到如下代码:

[ASP.NET Debugging BuggyBits读书笔记] Lab05 Crash_第2张图片

在Utility.cs里面找到如下代码:

[ASP.NET Debugging BuggyBits读书笔记] Lab05 Crash_第3张图片

可见程序出现问题的原因是,两个静态方法,循环引用,最终导致栈溢出。

 20110222补充:

Tess原文中提到了Process被shut down的三种情况:一是出现了2nd chance的 unhandled exception;二是进程被外部程序关闭;三是出现了严重的1st chance的exception导致程序被shutdown,这些exception包括heap corruption,stack overflow,fatal execution engine error和out of memory。其中进程被外部程序关闭或者出现严重的1st chance的错误导致进程退出的情况,都属于1st chance的情况。我们再进行debugging的时候,首先就是要判定是crash属于什么情况。对于这篇blog提到的情况,判定的逻辑如下:

1. 执行adplus -crash w3wp.exe -quiet之后,抓到的只有1st chance的dump而没有2nd chance的dump,排除第一种情况:unhandled exception导致进程crash。

2. 对于抓到的dump,使用WinDBG打开以后,当前活跃线程是0,执行kL得到如下结果:

  [ASP.NET Debugging BuggyBits读书笔记] Lab05 Crash_第4张图片

  可见这里是ThreadStart,这个线程只是一个普通的线程,而并非主线程。Tess的文章中提到,如果是crash的第二种原因,外部程序将进程结束,那么抓到的dump的活跃进程应该是主线程。而对于主线程,我们会看到WinMain函数入口点。


0:000> kL
ChildEBP RetAddr  
0014fbfc 7d503faf ntdll!ZwTerminateProcess+0x12
0014fc38 7d503f5a kernel32!_ExitProcess+0x4b
0014fc4c 79fd9e8f kernel32!ExitProcess+0x14
0014fe74 79f7479c mscorwks!SafeExitProcess+0x157
0014ff10 79004fab mscorwks!HandleExitProcessHelper+0x27
0014ff10 79004fab mscoree!CorExitProcess+0x46
0014ff20 77bcaddb mscoree!CorExitProcess+0x46
0014ff2c 77bcaefb msvcrt!__crtExitProcess+0x29
0014ff5c 77bcaf52 msvcrt!doexit+0x81
0014ff70 01001a3c msvcrt!exit+0x11 0014ffc0 7d4e7d2a w3wp!wmainCRTStartup+0x144 0014fff0 00000000 kernel32!BaseProcessStart+0x28
  因此,我们可以判断出导致进程crash的原因是第三种:fatal 1st chance error。对于这种情况,我们要对1st chance的error抓一个full user dump。

本文提到了使用adplus抓取first chance导致程序被shut down的情况,如果要使用DebugDiag,可以在设置rule的时候添加Kernel32!ExitProcess和Kernel32!TerminateProcess两个断点抓取full user dump

[ASP.NET Debugging BuggyBits读书笔记] Lab05 Crash_第5张图片

你可能感兴趣的:([ASP.NET Debugging BuggyBits读书笔记] Lab05 Crash)