如何处理系统崩溃后的Windows 7

如何处理系统崩溃后的Windows 7,第1张

如何处理系统崩溃后的Windows 7

想准备使用WindDbg来解决Windows 7系统崩溃,需要一台个人电脑满足下列要求:

32位或64位Windows 7/Vista/XP或Windows Server 2008/2003

约25MB的硬盘空间(这不包括存储转储文件符号文件的空间)

正常的互联网连接

微软Internet Explorer 5.0或更高版本

WinDBG的最新版本是Windows SDK中的一个选项。SDK下载文件名为winsdk web.exe,大小498KB,可以免费下载。(注意:安装调试器后,可以删除庞大的下载文件,从而腾出大量空间。)

内存转储(页面文件必须在C:上,以便Windows保存内存转储文件)

安装WinDbg

下载Windows SDK、运行安装向导程序后,选择Common Utilities(常用实用程序)下面的Debugging Tools for Windows(Windows调试工具)选项。

配置启动和恢复

这一步很烦人。因为不太容易找到启动和恢复对话框为了检查系统已设定成在错误检查期间采取合适的动作,包括要不要自动重新启动、保存多少大小的转储文件,需要这个对话框。

找到启动和恢复对话框:

1、选择屏幕左下角的Start(开始)按钮

2、选择Control Panel(控制面板)

3、选择System and Security(系统和安全)

4、从右边栏的选项中选择System(系统)

5、从左边栏中选择Advanced system settings(高级系统设置),显示SystemProperties(系统属性)对话框

6、在系统属性对话框中选择Advanced(高级)选项卡

7、在启动和恢复区中选择Settings(设置)按钮

看到如下所示的启动和恢复对话框:

确保启动和恢复设置是否正确

在System failure(系统故障)下

1、勾选Write an event to the system log(将事件写入系统日志)

2、勾选Automatically restart(自动重新启动)

3、选择Kernel memory dump(核心内存转储)

4、确保转储文件写入%SystemRoot%\MEMORY.DMP

5、勾选Overwrite any existing file(覆盖任何现有文件),以节省硬盘空间

请注意:这将意味着你的系统将既保存内核转储文件,又保存微型转储文件。然而,尽管你有一个微型转储用于每个事件,但保存的将是最近一个内核转储。

配置WinDbg

启动调试器:想启动WinDbg,请依次选择下列:

Start | All Programs | Debugging Tools for Windows| WinDbg

开始|所有程序| Windows调试工具|WinDbg

如果你要随时使用WindDbg,需要简化这个程序的启动:只要把它固定到Startup(启动)菜单上,或者发送快捷方式到桌面上。

符号有多重要?

在你想找到转储文件中的某个异常模块、急于挽救局面之前,得确保调试器已准备就绪。最重要的是,你得确信它会为你在排除故障的那个操作系统的确切版本找到符号文件。

符号表是编译后的产物。当某个程序被编译后,源代码从一种高级语言转换成了机器码。与此同时,编译器会创建一个符号文件,带有标识符列表、标识符在程序中的位置及其属性。一些标识符是全局和局部变量以及函数调用。程序不需要这些信息才能执行。因而,信息可以取出来存储在另一个文件中,减小了最终可执行文件的大小。

与较大的可执行文件相比,较小的可执行文件占用磁盘空间较少,加载到内存的速度较快。但凡事都有另一面:某程序引起问题时,操作系统只知道出现问题的十六进制地址。你需要比这更多的信息,才能确定哪个程序在使用该内存空间,它试图在进行什么操作。Windows符号表就能解答这个问题,而可以访问针对特定系统内存的符号好比将地名加在地图上。反过来,分析符号表错误的转储文件好比拿着一张波士顿的地图在旧金山找路。

配置WinDbg以定位符号

Windows有数量多得惊人的符号表文件。之所以这样,是因为操作系统的每个版本,甚至一次性版本,都会带来一个新文件。幸运的是,WinDbg可以为你处理这件事,但必须为它配置正确的搜索路径。要做到这一点,就要启动WinDbg,并依次选择下列:

File | Symbol file path

文件|符号文件路径

请注意:星号之间的地址表明你想把符号存储在何处,以便将来访问。比如说,我把符号存储在C:驱动器根目录下一个名为symbols的文件夹中,

打开内存转储时,WinDbg会查看可执行文件(.exe和.dll等文件),并提取版本信息。然后它会请求微软的符号服务器,该服务器包含该版本信息,并找到确切的符号表,从中获取信息。它不会下载你在排除故障的特定操作系统的所有符号,只会下载需要的符号。另外,你可以选择从微软下载并存储完整的符号文件。然而,对于你在分析的操作系统的每个版本而言,这个文件的大小在600MB到800MB之间。相比之下,WinDbg下载的文件不到100MB,即可分析测试机上操作系统的好几个版本。即使如今硬盘成本很低,节省的空间还是相当大。

关于转储文件

内存转储文件是一份快照,表明了系统崩溃时内存里面有什么。虽然内存转储文件也许是你可能需要查看的最乏味、最不直观的东西,但操作系统崩溃时,它是你最好的朋友。Windows创建了三种不同大小的内存转储:微型转储(minidump)、内核转储(kernel dump)和完全转储(full dump)。

1、小型转储或微型转储

Windows 7微型转储只有256K字节,不管从哪个标准来看都很小然而,它们比Windows 2000/XP时候大了不少,那时候只有64K。微型转储之所以这么小,原因之一是,它们不含有故障出现时,内存中的任何二进制文件或可执行文件。不过,那些文件对调试器在之后进行分析来说至关重要。只要你在创建转储文件的机器上调试,WinDbg就能在System Root文件夹中找到它们(除非转储文件创建后,二进制文件因系统更新而更改)。此外,调试器应该能够通过SymServ来找到它们。如果配置得当,除了内核转储外(下文有描述),Windows 7还会为每一次崩溃事件创建和保存微型转储。

2、内核转储

内核转储大小大致相当于Windows 7的内核占用的内存。在我的笔记本电脑上,内核转储约344MB大小,压缩后只有100MB多点。内核转储的一个优点是,它含有二进制文件。默认情况下,我总是让系统保存最近的内核转储。请记住:系统在保存内核转储时,也会保存微型转储。

3、完整转储或完全转储

完全内存转储大小相当于已安装内存的数量。由于许多系统有数GB内存,这方面的存储很快会成为问题,如果你频频遇到崩溃,更是如此。我通常不建议保存完全内存转储,因为它们占用太多的空间,而且一般也不需要。不过微软的Vachon倒建议:“如果你试图调试一个很复杂的问题,比如设备中多个服务之间的远程过程调用(RPC)问题,又想看看这些服务在用户模式下进行什么操作,完全内存转储就大有帮助。”因此,要坚持保存内核转储,但要准备偶尔创建完全转储。

如果没有内存转储可供使用,怎么办?

如果你没有内存转储可以查看,也不用担心,可以让系统崩溃!最简单的方法(不必更改注册表的设置)是,运行一个名为NotMyFault的出色工具(这要感谢Mark Russinovich和SysInternals网站的团队)。它提供了一系列选项,可以加载行为异常的驱动程序(这需要管理员权限)。

但记住:NotMyFault会制造系统崩溃!所以要让你的系统准备好,确信让需要访问该系统的任何人注销退出几分钟。凡是含有可能会丢失的信息的文件都要保存,并关闭应用程序。如果按上述方法配置了系统,它应该没有问题。机器应该会崩溃,重新启动,这样就有了内核转储和微型转储可以查看。我用过好多次,毫无问题。

下载NotMyFault,迫使系统崩溃

1、从下列微软网址下载NotMyFault工具,将文件提取到文件夹。

2、鼠标右击NotMyFault.exe,或者在命令提示符下,键入NotMyFault。如果看到“You don't have permission to open this file”(你没有权限打开此文件)的信息,那么再试一次,但是鼠标右击时,选择“Run as Administrator”(以管理员身份运行)。

3、从菜单中选择High IRQL fault (kernelmode))和Do Bug按钮。这将生成一个内存转储文件和“Stop D1”错误。

4、稍等一下...你的系统马上会回来,会有微型转储和内核转储可以查看了。

加载转储文件

如果你看到“你没有权限打开此文件”的信息,通过鼠标右击WinDbg来进行重新启动,选择“以管理员身份运行”。

一旦调试器运行,选择菜单选项File | Open crash dump(文件|打开崩溃转储),指向它,打开你想要分析的内存转储。如果你想让它记住转储文件在哪里,那么看到Save information for workspace(为工作区保存信息)时,选择Yes(确定)。

WinDbg会寻找Windows的这个确切版本的Windows符号文件。它引用符号文件路径,访问microsoft.com,并显示结果。

注意:如果调试器似乎很忙,那可能是第一次打开特定机器的转储文件,因而,WinDbg从SymServ下载符号。下次打开同一台机器的转储时,调试器似乎会快得多,因为符号文件已在本机上。

命令窗口会出现,崩溃分析显示在该窗口上。左下角将是KD>提示符。提示符右边是一个单行窗口,你可以在这里输入命令。

可能的错误信息

如果你看到信息:

ERROR: Symbol file could not be found. Defaulted to export symbolsfor ntoskrnl.exe -

错误:符号文件找不到。默认情况下导出ntoskrnl.exe的符号-

通常是下列三种情况中有一种出错了:

路径不正确仔细检查,确保之前输入的符号文件路径没有拼写错误或其他错误(如空白处)

连接失效,检查互联网连接,确保它在正常工作

防火墙禁止访问符号文件,或者符号文件在检索过程中已损坏

如果你的路径和连接没问题,那么问题可能出在防火墙上。如果防火墙一开始阻止WinDbg下载符号表,这会导致符号文件损坏。如果对防火墙解禁,再次试图下载符号文件仍不行,那么表明符号文件已损坏。最快的解决办法是关闭WinDbg,删除symbols文件夹(最有可能设成c:\symbols),并且对防火墙解禁。现在,重新打开WinDbg和转储文件。调试器会重新创建文件夹,并重新下载符号。

如果你看到这个信息:

Kernel symbols are WRONG. Please fix symbols to do analysis.

内核符号错误。请改正符号,进行分析。

那么,WinDbg无法检索正确的符号,它会改而使用默认的符号表。但是这个警告信息表明,它无法生成正确的结果。请记住:符号表是在程序编译时生成的,所以每个Windows版本、补丁和热修复程序等都有符号表文件。返回到前一个章节,确保你设置的路径正确、连接正常,而且没有被阻止。

从头到尾浏览WinDbg的输出。你可能会看到类似以下的错误信息,表明它可能找不到信息myfault.sys:

Unable to load image \??\C:\Windows\system32\drivers\myfault.sys,Win32 error 0n2

无法加载映像\??\C:\Windows\system32\drivers\myfault.sys, Win32 error 0n2

WARNING: Unable to verify timestamp for myfault.sys

警告:无法为myfault.sys验证时间戳

ERROR: Module load completed but symbols could not be loaded formyfault.sys

错误:模块加载已完成,但无法为myfault.sys加载符号

这意味着,调试器在寻找myfault.sys方面的信息。然而,由于它像第三方驱动程序(是的,它是由微软开发,但肯定不是平常的微软产品),它没有符号(微软并不存储所有第三方驱动程序)。可以忽视 该错误信息。供应商通常在交付驱动程序时不附带符号文件,符号文件并不是你所必要的没有符号文件,你也能找到有问题的驱动程序。

当你让WinDbg打开转储文件后,它会自动进行基本的分析。甚至不用给调试器下达任何直接命令,它已报出了可疑对象,如下面屏幕所示。

命令

有数百个命令可以控制WinDbgWinDbg是个功能很强大的工具。幸运的是,我们只需要一个命令。为了让探讨更深入一点,我们将多用两个命令,总共有三个命令。它们是!analyze –v、lmv和lmvm。

!analyze –v以详细模式分析!analyze –v显示了系统崩溃时,描述系统状态的信息,遇到的故障,以及谁是主要的可疑对象。

lmv显示加载模块的

详细信息lmv显示了一系列驱动程序及路径、版本和供应商信息。它常包含产品描述。lmv输出结果可能要很长的时间。留意WinDbg界面的左下角,你通常会看到kd>提示符。获取信息时,它会显示*BUSY*。只有kd>提示符返回后,你才能使用另外的命令。

lmvm

[模块名称]显示某加载模块

(模块名称)的

详细信息lmvm[模块名称]让你能够告诉调试器只获取那个特定模块的信息。比如说:lmvm myfault.sys。

!analyze -v

在命令窗口底部的命令行上输入!analyze -v(注意yynw命令与“-v”之间的空间)。V(详细)这个参数选项符告诉WinDbg,你想要所有的详细信息。它给出的解释结合了英语和编程术语,不过这是个良好的开头。实际上,在许多情况下,你可能不需要任何下一步操作。如果你明白了崩溃的原因,可能就搞定了。

下面这个例子是使用NotmyFault驱动程序来分析我们的崩溃。

如果使用!analyze –v,调试器输出结果的一个重要部分是堆栈文本。每次查看转储文件,总要关注堆栈最右边,留意任何第三方驱动程序。在本例中,我们看到了myfault。请注意:事件由下往上按年月顺序排列系统执行每个新任务时,新任务会显示在最上面,把以前的操作往下移。在这个很短的堆栈中,你会看到myfault处于活跃状态,然后出现页面错误,系统声明进行错误检查,这正是系统停止(蓝屏)的时候。请注意:部分数据已被清除,以便该内容能在一个页面上显示,“truncated”注释表明了这点。

用lmv来分析

下一步是确认可疑对象的存在,并找到有关它的任何详细信息。往命令行中输入lvm,可显示已加载的模块v指调试器以详细模式输出,显示模块的所有已知详细信息。

如果运行命令lmv后,你看到WinDbg的界面左下角出现*BUSY*(*忙碌*)信息,也不用担心。这是由于它在收集系统发生故障时,加载模块的详细信息收集过程可能需要几分钟。收集完毕后,你会在原来显示BUSY的地方看到kd>。

这里有大量信息。找到所要关注的驱动程序得花点时间,所以可通过选择Edit | Find(编辑|查找)来简化这个过程,然后输入可疑的驱动程序,这里是myfault。你看到的信息多少取决于驱动程序供应商。一些供应商把很少的信息放在文件中,而微软等另一些供应商往往把全面的信息放在文件中。

用lmvm来分析

想直接找到某个特定模块,一个好方法就是使用lmvm命令。在这种情况下,输入lmvm myfault,调试器将只返回针对该模块的数据。

你找到供应商的名称后,进入其网站,检查更新、知识库文章及其他支持信息。要是没有这些内容,或未能解决问题,请联系供应商。对方可能会要你把调试信息发过去(很容易把调试器的输出结果拷贝到电子邮件或Word文档里面),或者可能会要你把内存转储发过去(先进行打包,既为了压缩内存转储,又为了保护数据完整性)。

另外的三分之一

幸运的是,你一打开转储文件就知道原因的机率大概有三分之二。但有时转储文件提供的信息具有误导性,或者不够全面。这时候,又该怎么办呢?

有时原因出在硬件上

如果你老是遇到崩溃,又没有明确或一致的原因,可能出在内存问题上。下载免费测试工具Memtest86。这个简单的诊断工具运行速度快、效果好。许多人轻视内存问题的可能性,因为内存问题仅占系统崩溃的一小部分。然而,内存问题常常是害得你一直猜测的原因。

Windows是罪魁祸首吗?

很抱歉,这不可能!虽然可能有人会觉得很意外,但事实上,操作系统很少出错。如果ntoskrnl.exe(Windows核心)或win32.sys(主要负责Windows上GUI层的驱动程序)被列为是罪魁祸首——它们常常被这样列为,也不要过于草率地下定论。下面这种可能性大得多:某个异常的第三方设备驱动程序调用了Windows组件,以执行一项操作,然后传送了坏的指令,比如告诉它写入到根本不存在的内存。所以,尽管操作系统肯定会犯错,但你在怪罪微软之前先排除掉其他的所有可能性。

冤枉驱动程序

你经常会看到反病毒驱动程序被列为是崩溃的原因。比如说,使用!analyze -v后,调试器在“IMAGE_NAME”(映像名称)这一行报告反病毒软件的驱动程序。原因可能确实出在反病毒驱动程序上,不过要牢记:这类驱动程序被冤枉的可能性更大。原因如下:反病毒代码要工作,它必须监视所有的文件打开和关闭。为了做到这一点,代码处在操作系统的低层,而且在不断工作。实际上,该代码太忙碌了崩溃发生时,它常常出现在活跃的函数调用堆栈上,哪怕明明不是它导致崩溃,也这样。因为该堆栈上的任何第三方驱动程序立即成为可疑对象,所以反病毒驱动程序常常被列为崩溃的原因。不管是不是真的导致了问题,反病毒代码都经常出现在堆栈上。

缺少供应商信息?

一些驱动程序供应商并没有花时间把足够的信息附在模块后面。所以,如果lmv起不到帮助,试着查看映像路径上的子目录(如果有映像路径的话)。常常其中一个子目录就是供应商名称或者名称缩写。另一个办法就是用谷歌搜索引擎搜一下。输入驱动程序名称及/或文件夹名称。除了别人发布的关于该驱动程序的信息外,你可能还会找到相应的这家供应商。

总结

你已经花了时间来准备对付下一次蓝屏死机,记住:在大多数情况下,你打开转储文件后,立马就能知道原因,整个过程用不了一分钟。如此轻而易举地查明三分之二的严重故障的原因,真是让人满意——对你的用户们来说更是如此。

服务器技术之Perl语言的库

Perl支持对源代码的共享,通用于程序司以存放在文件中,并在程序中进行调用,这操作要通过require语句来实现,其格式如下:

require”cgi-lib.pl”:

它类似丁C语击中的#include预处理。Perl在查找源文件时,首先搜索缺省的库日录,然后搜索当前目录,也可以采用绝对路径指定文件名中的路径信息。

通过require函数的机制,可以把程序分割成多个文件并分别编写,以创建函数库。例如,在filel.pl中自定义好的Perl函数,现需要在file2.pl中使用该函数,可以用语句require(”filel.pl“)将它包含进来。当Perl中解释器执行到这一语句时,就在指定的目录中寻找文件filel.pl,

如果找到则执行文件中的语句,否则程序终止并输出错误信息。

Perl中还支持包的概念。在Perl中,程序把变量和子程序的名称存储到符号表中,这个符号表中的变量和子程序的集合就称为包(package)。在一个程序中可以定义多个包,每个包有一个单独的符号表,它定义的格式为:

package

packname

此语句定义个名为packname的包。在程序中,这个包定义语句以后的所有定义的变量和子程序名字,它们都存储在与该包关联的符号表中,直到遇到下一个package

语句为止。这样定义的好处是,与每个包相关的符号表有其自己的变量、子程序名空间,各个包中的变量是不相关的,因此可以在不同的包中使用相同的变量,而不会发生冲突。

在一个包中可以引用其它包中定义的变量或子程序,办法是在变量名前而加上包名和一个单引号。如:

$packname'var

在Perl中还支持模块,模块就是包含了变量和子程序的程序集合。使用use语句可以将已经存在的模块导入程序中,其格式如下:

use

module:

它导入了module模块,这样在模块module中定义的子程序和变量就可以使用了。取消导入的模块使用no语句,其格式为:

no

mnodule

它将取消module模块的导入。

Perl

5提供了些预定义模块,叫以用use导入并使用,下面是库中常用的一些模块:

Integer

整数运算模块

Diagnostics

诊断信息模块

Env

环境变量模块

POSIX

POSIX标准接口模块

Socket

网络套接字处理模块


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/162987.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-03-24
下一篇2023-03-24

发表评论

登录后才能评论

评论列表(0条)

    保存