理解Windows Vista和Windows 7中的崩溃转储文件 |
本文标签:Vista,Windows,7,崩溃转储文件 默认情况下,Windows配置为当系统发生崩溃时尝试自动抓取一个当前操作系统的状态信息 。接下来我们将讨论系统故障,非应用程序失败 。Dump选项可以通过控制面板中的系统工具来进行设置 。我们打开系统属性—高级选项卡,找到启动和故障恢复,点击设置,我们就可以看到Dump文件的相关配置 。当系统发生崩溃时,有3类Dump文件可以被捕获:
注意:有的情况下我们需要进行完全内存转储,手动进行完全内存转储为程序停止响应的排错提供了最为丰富的信息 。因为当程序Hang住时,我们需要查看用户态进程、死锁等等信息 。不过,当你在选择捕获哪种Dump文件时,一定要考虑好捕获出来的文件大小 。如上所述,完全内存转储文件大小会是在物理内存大小的基础上+1MB 。(笔者8GB内存,再加1MB 。恐怖啊……) 如果你担心页面文件设置过小,无法很好的捕获核心转储,我们唯一的办法就是通过KB244139所描述的方式使用CrashOnCtrlScroll方法造成手动崩溃 。系统重启之后,我们可以手工查看Dump文件大小 。另一种方法是在启动分区上手动设置2GB+1MB的页面文件大小(32位系统),这是因为32位操作系统内核态最大地址空间就是2GB 。 除了配置正确的页面文件大小之外,我们也需要确保有足够的磁盘空间让Dump文件能够被正确的写入 。与页面文件用来捕获Dump不同,Dump文件可以被写入其它的本地分区 。在保存多个Dump文件时,请取消选择“覆盖任何现有文件” 。不过请记住,这会给剩余的磁盘空间造成很大的压力 。 下面我们来看Dump文件是如何被产生的 。当系统启动时,会到注册表HKLM\System\CurrentControlSet\Control\CrashControl 读取崩溃转储选项 。所有在图形界面所做的操作都会修改如下注册表值:
如果你的系统超过2GB内存,在图形界面中你将不会看到完全内存转储选项 。其原因在KB274598中进行了描述 。但我们可以通过将HKLM\System\CurrentControlSet\Control\CrashControl下的CrashDumpEnabled值设置为1来强制启用它(改这个值在图形界面中完全内存转储仍不会显示出来) 。如果你需要完全内存转储来做更详尽的排错,也可以考虑使用Boot.ini中的MAXMEM开关将32位操作系统所使用的内存限制在2GB或更少(可以参考KB108393),此时系统就会将完全内存转储选项显示来 。 现在回到Dump文件如何被产生这个话题 。一旦转储功能被启用,操作系统会自动写一个以“Dump_”开头的磁盘迷你端口驱动到启动分区,并校验与创建 Dump文件相关的所有组件 。包括:磁盘迷你端口驱动、写入Dump文件的I/O管理函数和启动分区的页面文件 。最终所得的校验结果会被保存起来,每当系统启动时KeBugCheck函数会重新进行校验并与之前的结果相比对 。如果校验结果不匹配,将不会有Dump文件被写入磁盘(因为有破坏磁盘数据的危险);如果检验结果匹配,Dump信息会被写入已经被写到磁盘启动分区上的页面文件当中 。文件系统会被完全绕过,因为它也有可能是造成崩溃的原因之一 。当SMSS.EXE在启动过程中开启内存分页时,系统会仔细检查启动分区页面文件当中的信息 。如果有崩溃信息,这部分页面文件就会被保护起来 。如果启动过程中的所有或部分启动分区页面文件不可用,系统会提示虚拟内存过低(暂时) 。启动进程执行完成之后WINLOGON.EXE会调用SAVEDUMP.EXE进程从页面文件中抽出崩溃信息,并将Dump文件写到磁盘上 。 在Windows Server 2003上,某些过程可能会有不同,请参考KB886429 。当Server启动之后,Windows会要求在启动分区上创建一个和物理内存相同大小的临时文件 。如果磁盘空间不足,Dump还是会生成,不过会被系统缩减大小 。在创建Dump操作过程的初期,会话管理子系统(SMSS.EXE)就会介入验证内存Dump信息是否有效 。如果Dump信息有效,SMSS.EXE会将Dump文件重命名为Dumpxxx.tmp,进而存储Dumpxxx.tmp到启动分区并设置HKLM\System\CurrentControlSet\Control\CrashControl\MachineCrash下的TempDestination和DumpFile值 。SAVEDUMP.EXE便会读取这2个值,并在判定文件的有效性之后将Dumpxxx.tmp保存成Memory.dm |