使用Drwtsn32和NTSD进行崩溃进程转储

本文介绍了如何使用Drwtsn32和NTSD这两种Windows自带工具进行程序崩溃转储,并详细解释了它们的配置过程及注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用Drwtsn32NTSD进行崩溃进程转储

 

当我们的程序在客户那里崩溃时,使用崩溃转储工具获取崩溃现场的信息是很有必要的,否则单纯依赖用户的口头描述很难定位问题所在。Drwtsn32NTSDUserDumpAutodump+WinDbg都是Windows下的崩溃转储工具,其原理就是在程序崩溃时获取相应的信息并存储。Drwtsn32NTSDWindows自带的程序,客户系统中一定存在这个程序,我们可以方便的使用它进行崩溃转储。我们也可以自己编写一个类似的转储工具并注册成系统默认的调试器。我们也可以在进程内使用SetUnhandledExceptionFilter中注册一个ExceptionFilter函数,在这个函数中创建我们自己的转储工具生成转储信息。一般来说,当出现未处理的异常时,最好不要在ExceptionFilter函数中进行过多的处理并生成转储信息,因为这时程序的堆、栈可能已经不可用了。

 

使用Drwtsn32进行崩溃进程转储

首先运行”Drwtsn32 i”命令把Drwtsn32设置为默认的调试器。然后运行Drwtsn32设置转储选项,一般使用默认的选项就行了。选项如下图所示:

如果想在进程崩溃时得到通知可以选择视觉通知和声音通知。如果不选择附加到现有日志文件,则每次程序出错都创建新的日志文件,会把以前的日志文件覆盖,所以最好选择附加到现有日志文件。转储文件默认保持到“C:/Documents and Settings/All Users/Application Data/Microsoft/Dr Watson/user.dmp“,新生成的转储文件user.dmp会把以前的转储文件覆盖,这是Drwtsn32非常不方便的一个地方,它不能为每个文件生成一个唯一的文件名。

 

使用NTSD进行崩溃进程转储

NTSDWindows 2k/XP自带的调试器,虽然它的版本比较老(与最新的WinDbg附带的版本相比),不过用来做崩溃进程转储已经够用了。首先需要手工把NTSD设置为默认的调试器,打开注册表,

设置“HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/AeDebug/Debugger”为

c:/windows/system32/ntsd.exe -p %ld -e %ld -g -c ".dump /m /u D:/dump.dmp;q"”。

设置后转储文件会放在D盘根目录下面,每个文件都有一个唯一的文件名,文件名格式是“dump_日期_时间_进程ID_.dmp

设置“HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/AeDebug/Auto”为1.

NTSD命令参数的具体含义可以参考WinDbg的文档。NTSD可以为每个转储文件生成唯一的文件名,所以不用担心文件互相覆盖的问题。

 

有了转储文件我们就可以使用WinDbgVisual Stdio慢慢分析了。

 
<think>我们正在讨论的是在Windows程序中自动生成Dump文件的方法。根据引用内容,我们可以通过程序自身在崩溃时捕获异常并生成Dump文件,而不依赖于系统自带的调试工具(如drwtsn32NTSD等)。主要步骤包括设置未处理异常过滤器调用MiniDumpWriteDump函数。 下面我将详细说明实现步骤: ### 1. 设置未处理异常过滤器 使用Windows API函数`SetUnhandledExceptionFilter`来设置一个顶层的异常处理函数。这个函数将在程序发生未处理异常时被调用。 ### 2. 编写异常处理函数 在异常处理函数中,我们将调用`MiniDumpWriteDump`函数来生成Dump文件。这个函数需要指定Dump文件的类型(如MiniDumpNormal、MiniDumpWithFullMemory等),以及异常信息等。 ### 3. 生成Dump文件 在异常处理函数中,我们需要: - 创建文件用于写入Dump数据。 - 填充`MINIDUMP_EXCEPTION_INFORMATION`结构体,提供异常信息。 - 调用`MiniDumpWriteDump`函数。 ### 4. 注册异常处理函数 在程序启动时(如main函数开始处)调用`SetUnhandledExceptionFilter`注册我们的异常处理函数。 ### 示例代码 以下是一个C++的示例代码,展示如何实现自动生成Dump文件: ```cpp #include <Windows.h> #include <DbgHelp.h> #include <tchar.h> #include <time.h> #pragma comment(lib, "DbgHelp.lib") // 异常处理函数 LONG WINAPI MyUnhandledExceptionFilter(EXCEPTION_POINTERS* pExceptionInfo) { // 生成Dump文件名,包含时间戳以便区分 TCHAR szFileName[MAX_PATH] = {0}; TCHAR szProcessName[MAX_PATH] = {0}; GetModuleFileName(NULL, szProcessName, sizeof(szProcessName) / sizeof(TCHAR)); TCHAR* pszProcessName = _tcsrchr(szProcessName, '\\'); if (pszProcessName) pszProcessName++; else pszProcessName = szProcessName; SYSTEMTIME stLocalTime; GetLocalTime(&stLocalTime); _stprintf_s(szFileName, _T("%s_%04d%02d%02d_%02d%02d%02d.dmp"), pszProcessName, stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay, stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond); // 创建Dump文件 HANDLE hDumpFile = CreateFile(szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hDumpFile != INVALID_HANDLE_VALUE) { // 初始化Dump信息 MINIDUMP_EXCEPTION_INFORMATION dumpInfo; dumpInfo.ThreadId = GetCurrentThreadId(); dumpInfo.ExceptionPointers = pExceptionInfo; dumpInfo.ClientPointers = FALSE; // 写入Dump文件 MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, // 也可以使用其他参数,如MiniDumpWithFullMemory等 &dumpInfo, NULL, NULL); CloseHandle(hDumpFile); } // 返回异常处理结果,这里我们选择终止程序 return EXCEPTION_EXECUTE_HANDLER; } int main() { // 设置未处理异常过滤器 SetUnhandledExceptionFilter(MyUnhandledExceptionFilter); // 这里开始你的程序逻辑 // ... // 下面是一个故意引发崩溃的测试代码 int* p = nullptr; *p = 42; // 这将引发一个访问冲突异常 return 0; } ``` ### 关键点说明 - **Dump文件类型**:`MiniDumpWriteDump`函数的第四个参数指定Dump文件包含的信息量。`MiniDumpNormal`包含基本的信息(如线程、堆栈等),而`MiniDumpWithFullMemory`会包含整个进程的内存,文件较大但信息更全[^3]。 - **文件名生成**:示例中使用进程时间戳来生成唯一的Dump文件名,避免覆盖。 - **异常处理返回值**:`EXCEPTION_EXECUTE_HANDLER`表示异常已被处理,程序将终止。如果需要继续运行程序,则不能使用此返回值(但通常崩溃后继续运行是不安全的)[^3]。 ### 注意事项 1. 需要链接`DbgHelp.lib`库,并包含`DbgHelp.h`头文件。 2. 在64位程序中,需要确保编译选项正确,并且使用64位版本的DbgHelp.dll(或者使用系统自带的,通常位于System32目录下)。 3. 生成的Dump文件可以使用Visual Studio或WinDbg打开分析。 ### 相关问题 1. 如何配置`MiniDumpType`以平衡Dump文件大小信息完整性? 2. 在分布式系统中如何自动收集崩溃生成的Dump文件? 3. 如何解析Dump文件中的异常调用堆栈? 4. 使用WinDbg进行崩溃分析有哪些常用命令? [^1]: 引用自用户提供的关于Java生成Dump文件的说明。 [^2]: 引用自用户提供的关于Windows下程序崩溃生成Dump文件的说明。 [^3]: 引用自用户提供的C++实现Windows程序崩溃自动生成Dump文件的说明。</think>### Windows 程序自动生成 DMP 文件的方法 在 Windows 程序中自动生成 DMP 文件(内存转储文件)是调试崩溃分析程序状态的关键技术。以下是三种主要实现方式: #### 一、程序内嵌自动捕获(推荐方法) ```cpp #include <Windows.h> #include <DbgHelp.h> #pragma comment(lib, "DbgHelp.lib") // 异常处理函数 LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS* pExp) { // 生成带时间戳的文件名 char fileName[MAX_PATH]; SYSTEMTIME st; GetLocalTime(&st); sprintf(fileName, "Crash_%04d%02d%02d_%02d%02d%02d.dmp", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); // 创建DMP文件 HANDLE hFile = CreateFileA(fileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { MINIDUMP_EXCEPTION_INFORMATION mdei = { GetCurrentThreadId(), pExp, FALSE }; // 写入DMP文件(选择适当的信息级别) MiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(), hFile, static_cast<MINIDUMP_TYPE>(MiniDumpWithDataSegs | MiniDumpWithHandleData), &mdei, NULL, NULL); CloseHandle(hFile); } return EXCEPTION_EXECUTE_HANDLER; // 终止程序 } // 程序初始化时注册 int main() { SetUnhandledExceptionFilter(ExceptionHandler); // 主程序代码... } ``` #### 二、外部工具捕获(无需修改代码) 1. **Dr. Watson (drwtsn32)** - 系统内置工具,自动捕获未处理异常 - 配置注册表启用: ```regedit [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DrWatson] "Auto"=dword:00000001 "DumpAllThreads"=dword:00000001 "DumpSymbols"=dword:00000001 ``` 2. **ProcDump (Sysinternals 工具)** ```bash procdump -ma -e -w YourApp.exe ``` - `-ma`: 完整内存转储 - `-e`: 在未处理异常时触发 - `-w`: 等待进程启动 #### 三、崩溃后分析(关键步骤) 1. **使用 Visual Studio 分析**: - 菜单 > 文件 > 打开 > 崩溃转储文件 - 加载匹配的 PDB 符号文件 - 点击"使用仅限本机进行调试" 2. **WinDbg 基本命令**: ```windbg !analyze -v # 自动分析崩溃原因 .excr # 显示异常记录 kv # 显示调用堆栈 !peb # 查看进程环境块 lm # 列出加载模块 ``` #### DMP 类型对比表 | 类型标志 | 文件大小 | 包含信息 | 适用场景 | |----------|----------|----------|----------| | `MiniDumpNormal` | 小 | 线程+堆栈 | 快速分析 | | `MiniDumpWithDataSegs` | 中 | +全局变量 | 常规调试 | | `MiniDumpWithFullMemory` | 大 | 完整内存镜像 | 复杂内存问题 | | `MiniDumpWithHandleData` | 中 | +句柄信息 | 资源泄漏分析 | > 提示:生产环境建议使用 `MiniDumpWithDataSegs | MiniDumpWithHandleData` 平衡信息量文件大小[^3] #### 最佳实践 1. **版本匹配**:DMP 文件必须与编译时的 PDB 符号文件匹配 2. **异常处理**:捕获异常后应立即生成 DMP,避免后续操作破坏现场 3. **错误报告**:可集成自动上传功能(如 HTTP 上传到服务器) 4. **64位注意**:32/64 位程序需使用对应版本的 DbgHelp.dll > 在分布式系统中,可通过监控服务自动收集 DMP 文件并关联日志分析[^1] --- ### 相关问题 1. 如何配置 DMP 文件生成路径命名规则? 2. 在 .NET 程序中如何自动生成 DMP 文件? 3. 如何解析 DMP 文件中的内存泄漏问题? 4. Linux 系统下如何生成类似的核心转储文件? 5. 如何减小生产环境 DMP 文件的大小? [^1]: 引用自用户提供的关于 Java 生成 dump 文件的说明 [^2]: 引用自用户提供的关于 Windows 下程序崩溃生成 dump 文件的解释 [^3]: 引用自用户提供的 C++ 实现 Windows 程序崩溃自动生成 Dump 文件的代码示例
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值