前言
我们在 内核转储,开抓啦! 这篇文章里介绍了一个关键的系统设置。设置好后可以让系统在蓝屏(Blue Screen of Death,简称 BSOD
)的时候自动保存转储文件。那篇文章只是简单的介绍了设置步骤,本文力求详细的介绍相关内容。
我们先根据下面的动图回顾一下设置步骤:
不知道大家有没有想过这些设置保存在哪里了呢?我猜保存在注册表里。是不是呢?我们一起来看看吧。
保存位置
为了找到这些设置保存的位置,我特意用 process monitor
捕获了整个设置过程,并录制了一段视频。
根据调查结果可知,转储类型
保存在注册表如下位置: HKLM\System\CurrentControlSet\Control\CrashControl\CrashDumpEnabled
。每一项对应的值如下表:
中文名 | 英文名 | 值 |
---|---|---|
(无) | (None) | 0 |
小内存转储(256KB) | Small memory dump | 3 |
核心内存转储 | Kernel memory dump | 2 |
完全内存转储 | Complete memory dump | 1 |
自动内存转储 | Automatic memory dump | 7 |
活动内存转储 | Active memory dump | 1 |
我们可以发现, 完全内存转储
和 活动内存转储
设置的 CrashDumpEnabled
的值居然一样,都是 1。肯定有其它地方不一样。把过滤条件改为 Path
begins with
HKLM\System\CurrentControlSet\Control\CrashControl
,
继续观察,得到的对比结果如下。
经过对比我们发现,当设置为 活动内存转储
时,会设置注册表项HKLM\System\CurrentControlSet\Control\CrashControl\FilterPages
的值为 1
,当设置为 完全内存转储
时,会删除 FilterPages
子项。
说明:win7
及更早的系统中没有自动内存转储
和活动内存转储
选项。自动内存转储
是从win8
开始引入的。活动内存转储
是从win10
开始引入的。
其它相关设置
除了指定转储类型
,我们还可以进行其它设置。
转储文件:
指定转储文件保存的位置。对于
小内存转储
,指定的是转储文件保存的目录,默认是%SystemRoot%\Minidump\
。对于其它几种转储类型,指定的是转储文件的保存路径,默认是%SystemRoot%\MEMORY.DMP
。自动重新启动(R)
选项:如果勾选,可以让系统在蓝屏后自动重启。将事件写入系统日志(W)
选项:如果勾选,可以把蓝屏事件记录到系统日志里。覆盖任何现有文件(O)
选项:如果勾选,覆盖已存在的同名文件,否则不覆盖(如果已经有同名文件,本次蓝屏的转储文件不会生成)。此选项对小内存转储
不生效。禁止在磁盘空间不足时自动删除内存转储(A)
选项:如果勾选,即使在磁盘空间不足时也不删除之前保存的转储文件。此选项在win7
中不存在,是在更高版本的操作系统中引入的。
每一项在注册表中的对应位置,请参考如下代码。保存为 .reg
文件,双击即可导入。
Windows Registry Editor Version 5.00
; 将事件写入系统日志。 1 表示写入,0 表示不写入
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\CrashControl]
"LogEvent"=dword:00000000
; 是否自动重启。1 表示自动重启,0 表示不自动重启
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\CrashControl]
"AutoReboot"=dword:00000000
; 转储类型。每个值的意义参考上表
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\CrashControl]
"CrashDumpEnabled"=dword:00000001
; 转储文件的保存路径。以二进制形式表示的 UNICODE 路径。默认值是 %SystemRoot%\MEMORY.DMP
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\CrashControl]
"DumpFile"=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,\
74,00,25,00,5c,00,4d,00,45,00,4d,00,4f,00,52,00,59,00,2e,00,44,00,4d,00,50,\
00,00,00
; 小内存转储文件保存路径。以二进制形式表示的 UNICODE 路径。默认值是 %SystemRoot%\MEMORY.DMP
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\CrashControl]
"MinidumpDir"=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,\
00,74,00,25,00,5c,00,4d,00,69,00,6e,00,69,00,64,00,75,00,6d,00,70,00,00,00
; 小内存转储文件保存的最大个数。如果转储文件数量超过此值,则删除最旧的那个。
; 界面上没有对应的设置,只能通过注册表修改。
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\CrashControl]
"MinidumpsCount"=dword:00000005
; 覆盖任何现有文件。1 表示覆盖,0 表示不覆盖。对小内存转储不生效。
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\CrashControl]
"Overwrite"=dword:00000001
; 禁止在磁盘空间不足时自动删除内存转储。 1 表示不删除,0 表示删除
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\CrashControl]
"AlwaysKeepMemoryDump"=dword:00000000
各种转储类型介绍
关于这几种转储类型的介绍,主要翻译自微软官方文档,但不完全是。喜欢看英文文档的小伙伴儿请参考微软官方文档。
- 完全内存转储
包含操作系统使用的所有物理内存。默认不包含平台固件占用的物理内存。为了确保转储文件可以顺利生成,请确保引导盘上的页面文件大小至少是物理内存大小 + 1 MB(写转储文件时需要一些头信息)。假设,物理内存是
4GB
,我们需要保证初始大小至少是4097MB
。当然设置成更大的值也没关系。我们可以按下图进行设置:
- 活动内存转储
活动内存转储
类似于完整内存转储
,但是会过滤掉不太可能与排除故障相关的页面。由于这种过滤,产生的转储文件通常比完整内存转储
小得多。这种类型的转储文件包含分配给用户模式应用程序的任何内存。它还包括分配给
Windows
内核和硬件抽象层(HAL
)的内存,以及分配给内核模式驱动程序和其他内核模式程序的内存。转储文件包括映射到内核或用户空间的对调试有用的活动页面,还包括选择的以分页文件为后备的转换、备用和修改页面,比如使用VirtualAlloc
或以分页文件为后备的内存区域。活动内存转储
不包括空闲列表、零列表、文件缓存、客户虚拟机页面和其他各种类型的不太可能对调试有用的内存。当目标系统中托管了虚拟机的时候,
活动内存转储
特别有用。完全内存转储
会包含所有虚拟机占用的内存,而活动内存转储
不会。活动内存转储 在 Windows 10 或更高版本的系统中可用。
- 核心内存转储
包含了系统崩溃时内核所使用的物理内存。
这种转储文件比完整内存转储小得多。
核心内存转储
不包括未分配的内存,或分配给用户态应用程序的任何内存。它只包括分配给Windows
内核和硬件抽象层(HAL
)的内存,以及分配给内核模式驱动程序和其他内核模式程序的内存。大多数情况下,这种类型的崩溃转储是最有用的。它比完全内存转储小得多,但是它只忽略了那些不太可能涉及崩溃的内存部分。
由于这种转储文件不包含崩溃时驻留在内存中的任何用户模式可执行文件的映像,所以如果这些可执行文件非常重要,您可能还需要设置可执行映像路径。
- 自动内存转储
自动内存转储
与核心内存转储
包含相同的信息。两者的区别不在于转储文件本身,而在于Windows
设置系统分页文件大小的方式。如果系统分页文件大小设置为
系统管理的大小(Y)
,转储类型设置为自动内存转储
,那么Windows
可以将分页文件大小设置的比物理内存还要小。在这种情况下,Windows
将分页文件的大小设置得足够大,以确保在大多数情况下可以捕获核心内存转储。如果系统崩溃,而分页文件的大小不足以保存核心内存转储,则
Windows
会将分页文件的尺寸增加到至少物理内存的大小。此事件(增大分页文件尺寸的事件)发生的时间会被记录在注册表项HKLM\SYSTEM\CurrentControlSet\Control\CrashControl\LastCrashTime
中。增加后的分页文件大小将保持
4
周,然后恢复到之前较小的值。如果希望在4
周之前就恢复到之前较小的值,可以删除此注册表项。自动内存转储在 Windows 8 或更高版本的系统中可用。
小内存转储(
256 KB
)小内存转储包含如下内容:
- 错误检查信息和参数,以及其它蓝屏数据。
- 崩溃的处理器上下文(
PRCB
)。 - 崩溃进程的进程信息和内核上下文(
EPROCESS
)。 - 崩溃线程的线程信息和内核上下文(
ETHREAD
)。 - 崩溃线程的内核模式调用堆栈。如果它大于
16 KB
,则只包含最前面的16 KB
。 - 加载的驱动程序列表。
在
Windows XP
和Windows
的后续版本中,还包括以下内容:- 已加载模块和已卸载模块的列表。
- 调试器数据块。它包含关于系统的基本调试信息。
Windows
标识为对调试失败有用的任何附加内存页。这包括发生崩溃时寄存器所指向的内存页,以及故障组件特别请求的其他内存页。- (
Windows Server 2003
及更高版本)The Windows SKU
—— 比如,"Professional" 或者 "Server"。关于
Windows SKU
可以参考链接 https://www.thewindowsclub.com/windows-7-versions-sku
总结
小内存转储(256KB)
默认会保存到%SystemRoot%\Minidump
文件夹下,其它几种类型的转储文件默认保存到%SystemRoot%\Memory.dmp
。- 各种转储类型产生的转储文件中包含的信息不一样,根据自己的需要选择。产生的转储文件大小排序如下:
完全内存转储
>活动内存转储
>核心内存转储
=自动内存转储
>小内存转储
。 - 系统蓝屏后是否自动重启,是否保存转储文件,是否覆盖现有文件,转储文件保存类型,转储文件保存位置等相关设置都在注册表项
HKLM\System\CurrentControlSet\Control\CrashControl\
下,可以根据需要修改本文中的代码,并另存为.reg
文件,双击导入系统即可。注意需要重启生效。 - 如果在调试的时候遇到了
missing page
错误,可以使用.ignore_missing_pages
命令。 - 在
process monitor
的帮助下,没查看任何帮助文档就把各个类型的转储文件对应的值及保存位置调查清楚了!process monitor
真是调查此类问题的神兵利器!你值得拥有!
参考资料
- https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/varieties-of-kernel-mode-dump-files
- https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/complete-memory-dump
- https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/active-memory-dump
- https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/kernel-memory-dump
- https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/automatic-memory-dump
- https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/small-memory-dump