天下网吧 >> 网吧天地 >> 网吧技术 >> 网吧软件 >> 正文

Windows系统IE和WMP随机崩溃案例

2009-1-7不详佚名
前段时间我家里的64位游戏主机上的IE崩溃了,我以为是某个IE的第三方插件内存错误引起的。我没管它,结果过了几天IE又崩溃了。然后,WMP也开始崩溃了,用个3、4次就要崩溃一次:

 

randcrash0.png

 

    几个程序的崩溃似乎在告诉我这是一个更底层的问题。我之前把我的CPU超频了,所以怀疑这一连串的程序崩溃是由CPU过热引起的,然后很不情愿的把CPU倍频调回出厂设置。但令人沮丧的是,崩溃问题并没有改善。我又怀疑是不是内存出了问题,但是Windows Vista的内存诊断程序并没有找到任何问题。

    貌似硬件不是问题了,我的下一步行动是检查一下进程崩溃转储,看看能不能找到什么线索。不过我首先得把转储文件找出来。Windows XP的应用程序错误报告程序会在显示程序崩溃对话框之前就生成转储文件,这样你只要点击查看报告详情然后查阅报告的技术信息就可以找到转储文件的位置了:

randcrash1.png

 

    相对应的Windows Vista的对话框并不提供报告的技术信息,而且除非微软的Windows错误报告服务器主动要求(通常只有收到大量相同的错误报告才会这样),也不会进行转储。不过还好,显示错误对话框的程序WerFault会在你点击关闭程序按钮之前保留崩溃的进程,这样就为我们把调试器附到进程进行检查提供了机会。你可以在Process Explorer里面看到WerFault连接到崩溃的WMP的句柄:

  

randcrash12.png

 

    等我的WMP再次崩溃的时候,我打开WinDbg,这是调试工具中的Windows调试程序,可以从微软网站上下载。在确认符号配置正确无误地设置到微软的符号服务器(例如:srv*c:\symbols*http://msdl.microsoft.com/download/symbols)后,就可以打开文件菜单选择“附到一个进程...”:

   

randcrash3.png
   随后会显示选择进程对话框,可以在里面找到崩溃的进程。选定之后,WinDbg把他打开,显示一个跟打开转储文件差不多的界面。两者的区别是:当你打开转储文件时,可以执行!analyze命令,这个命令能启发式地分析出崩溃的原因,而在你附到一个进程的时候,这个命令只能告诉你由一个调试程序附到了这个进程上:

  

randcrash4.png

 

下载 (107.7 KB)
2008-6-24 19:21


 

    附到进程时要找到潜在的崩溃原因,需要检查进程中每一个线程的堆栈,所以我从查看菜单中打开“进程和线程”和“调用堆栈”对话框

   

randcrash6.png

 

    在线程对话框中选取第一个项目开始检查:

   

randcrash7.png

 

    在“调用堆栈”窗口弹出后,会显示崩溃时所选线程的函数嵌套,这时WinDbg 会从符号服务器取回符号数据,所以WinDbg 的命令窗口会变成灰色不可用状态。我检查了每一个线程的堆栈,来回的按方向和回车键去寻找名字里带“exception“或者”fault“的函数,以及它所在的线程。在接近列表尾部的地方我无意间发现了这个:

   

randcrash8.png
    我注意到在列表的顶部有很多函数名字里带“Exception“。顺着列表往下看(堆栈的上部),我看到Nvappfilter中一个被称作”Kernel32.dll的HeapFree函数“的函数,接着进程便崩溃了。堆释放例行程序中的例外意味着要么调用程序传递了一个错误的堆地址,要么在函数执行的时候堆已经被破坏了。如果调用程序是一个Windows DLL我会怀疑是后一个原因,但是在这种情况下,调用程序是一个第三方的DLL(之所以知道是第三方DLL是因为WinDbg找不到它的符号信息,也就不知道里面的函数的名字)。我使用lm(列出模块)命令找出了关于它的版本信息,从而确认了这一点:

 

randcrash9.png

 

    Nvappfilter现在是首要嫌疑,但我现在还缺乏直接证据。我继续运行系统,然后用相同的方法分析了后面的几次崩溃。不管是IE、WMP或是游戏,出错的堆栈都是相同的,都是Nvappfilter调用HeapFree。这虽然不能作为决定性的证据,但是作为旁证已经很足够了。

    我随后上网查找看有没有Nvappfilter 的升级,但是我并不知道Nvappfilter 在哪一个软件包中。我把它输入搜索引擎,发现它是nVidia的FirstPacket功能的一部分。 FirstPacket被用来提高游戏的网络通信的优先级,是nForce主板自带软件的一部分:

   

randcrash10.png

 

    我到nVidia的网站上去下载了一份最新的nForce驱动程序,但是Nvappfilter.dll并没有更新,所以我还是得忍受程序崩溃。nVidia控制面板没有什么选项可以阻止Nvappfilter的载入,所以我只能手动把他禁用。我并不使用FirstPacket,因为我之前根本不知道这个功能,但是我要搞清楚它是怎么样让Windows加载它的。所以我转而求助于Autoruns,随后在Winsock Layered Service Provider (LSP)部分找到了对Nvappfilter 32位版和64位版的引用:

   

randcrash11.png

 

下载 (126.94 KB)
2008-6-24 19:21

    我把和Nvappfilter 有关的项目都删掉了,重启系统然后直到现在也没有程序崩溃的情况发生。我在写这篇文章的时候又去看了一下nForce 的驱动程序有没有更新Nvappfilter。最新的驱动程序好像已经不再包含Nvappfilter 或者其他的Winsock LSP,所以就算是Nvappfilter引起的故障,现在也不成问题了。

    在研究这些崩溃的时候我还做了另外一件事就是好好的利用了Vista SP1的“本地转储“功能,它可以在程序崩溃的时候自动生成转储文件供我研究。只要新建一个注册表键HKLM\Software\Microsoft\Windows\Windows Error Reporting\LocalDumps,WerFault就会帮你生成”本地转储“了。默认情况下转储文件被放在%LOCALAPPDATA%\Crashdumps,不过你也可以利用注册表键值修改默认位置,还能指定WerFault保留多少分转储文件。

本文来源:不详 作者:佚名

声明
声明:本站所发表的文章、评论及图片仅代表作者本人观点,与本站立场无关。文章是出于传递更多信息之目的。若有来源标注错误或侵犯了您的合法权益,请作者持权属证明与本网联系,我们将及时更正、删除,谢谢。 Email:support@txwb.com,系统开号,技术支持,服务联系微信:_WX_1_本站所有有注明来源为天下网吧或天下网吧论坛的原创作品,各位转载时请注明来源链接!
天下网吧·网吧天下
  • 本周热门
  • 本月热门
  • 阅读排行