概述
在Windows中,收集应用层dump的方法有很多。可以用procdump,可以用Windbg,可以用任务管理器,也可以用Visual Studio附加后转储。但是,这些方法都需要额外的用户操作。当客户环境出现崩溃后,使用这些工具都或多或少存在一些不便。有没有一种方法可以不使用额外工具就能在崩溃时收集Dump呢?那就是使用Windows Error Reporting!
这项功能从Windows Vista With SP1和Windows Server 2008开始就内置于Windows中。可以在用户模式进程崩溃时,收集并存储Dump。但是不支持应用程序自己进行崩溃报告,也不支持.Net应用程序。
使用方式
首先,自动收集Dump的功能默认是关闭的。所以需要启用并设置该功能。在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps
注册表键下创建以下值:
值名称 | 描述 | 类型 | 默认值 |
---|---|---|---|
DumpFolder | dump文件的存放路径。如果不使用默认路径,请确保指定文件夹有允许崩溃进程写入数据的访问权限。对于服务崩溃,会根据服务账户的配置将dump写入指定配置目录。例如,System服务的配置目录是%WINDIR%\System32\Config\SystemProfile 。而Network和Local Services的目录是%WINDIR%\ServiceProfiles 。 |
REG_EXPAND_SZ | %LOCALAPPDATA%\CrashDumps |
DumpCount | 目录中的最大dump文件数量。达到最大数量后,新dump文件会替换最老的dump文件 | REG_DWORD | 10 |
DumpType | 0:自定义dump。1:Mini dump。2:Full dump。 | REG_DWORD | 1 |
CustomDumpFlags | 用于自定义dump选项。这个值只有DumpType为0是使用。是MINIDUMP_TYPE枚举结构的按位组合。 | REG_DWORD | 0x00000121(MiniDumpWithDataSegs、MiniDumpWithUnloadedModules、MiniDumpWithProcessThreadData) |
如果为指定应用程序设置了自动调试则不会收集Dump文件
还可以为指定应用程序进行独立配置,例如HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\Windows Error Reporting\LocalDumps\Test.exe
键,然后在该键下创建dump设置即可。
实际操作
首先,我编写如下代码:
1 | int wmain(int argc, wchar_t** argv) |
将上述代码编译为Test.exe
然后配置注册表以启用WER的Dump自动收集功能:
从上图可以看到我只在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps
键下配置了DumpFolder,值为%HOMEPATH%\Desktop\CollectDump
。表示会将所有程序的崩溃都放置于这个路径。我尝试运行上面写好的Test.exe,发现该路径出现了一个dump文件(Test.exe.6356.dmp):
1 | 文件夹 PATH 列表 |
接下来我们尝试自定义Dump配置,在LocalDumps下创建一个新的项Test2.exe,并设置DumpFolder值为%HOMEPATH%\Desktop\CollectDump2
。
将Test.exe重命名为Test2.exe,并再次尝试启动,发现在新路径CollectDump2
中创建了新的dump文件:
1 | C:. |
PermaLink:
https://lazywang.life/2022/01/24/Collecting-UserMode-Dumps-By-WER/