|
简单地说,用户态转储文件(User Mode Dump)就是用于保存应用程序在某一时刻运行状态的二进制文件。为了支持调试,Windows系统定义了用户态转储文件的格式并提供了API来创建和读取用户态转储文件。与描述整个系统状态的系统转储文件相比,用户态转储文件的描述范围仅限于用户进程,二者的格式也是不同的。 在Windows的很多文档中,用户态转储文件被称为MiniDump,意思是小型的转储文件,但这个名字并不总是确切的,因为我们也可以产生包含完整内存数据的非常庞大的转储文件。 用户态转储文件(User Mode Dump)对于产品期调试、调试难以复现的随机问题和调试内存泄漏等问题都有有着重要价值。《软件调试》一书的第12.9节详细介绍了用户态转储文件的格式和用途以及分析方法。 UdmpView工具用来显示用户态转储文件中包含的各类数据流。既可以显示每种数据流的原始数据(Raw Data),也可以把固定类型的信息以结构化的形式显示出来。 使用方法UdmpView程序的界面很简单(见下图),所有操作都列在左侧。右侧的两个列表框用来显示命令的执行结果。上面的列表框用来显示当前转储文件中所包含的所有数据流。下面的列表框用来显示数据流的详细内容或者命令的其它执行结果。各个命令按钮的功能如下:
下图是使用UdmpView观察一个用户态转储文件(可以在本页下方下载)时的一个截图。 内容框中目前显示了异常数据流、系统信息数据流和部分原始数据。 |
安装方法目前,UdmpView只由一个文件组成,即UdmpView.exe。只要通过下面的链接下载压缩包后,将其中的文件解压缩到你喜欢的位置就可以了。 |
内部实现UdmpView是使用Windows SDK中的MiniDump系列API而开发的。使用这些API读取数据流之前,应该先使用文件访问API打开文件,然后映射到当前进程的内容空间中。例如,以下是UdmpView程序用来执行打开操作的Open方法的源代码: HRESULT CMdmpParser::Open(LPCTSTR lpszFileName,HWND hWndStreamList)
{
PMINIDUMP_HEADER pMdpHeader;
char szSignature[sizeof(ULONG32)+1];
m_hDumpFile=CreateFile(lpszFileName,
GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if(m_hDumpFile==INVALID_HANDLE_VALUE)
{
OutMsg(_T("Failed to CreateFile(%s) for 0x%x"),
lpszFileName,GetLastError());
return E_FAIL;
}
m_hDumpMapFile=CreateFileMapping(m_hDumpFile,
NULL, PAGE_READONLY, 0, 0, NULL);
if(m_hDumpMapFile==NULL)
{
OutMsg(_T("Failed to CreateFileMapping(0x%x) for 0x%x"),
m_hDumpFile,GetLastError());
return E_FAIL;
}
m_pBaseofDump=MapViewOfFile(m_hDumpMapFile, FILE_MAP_READ, 0, 0, 0);
if(m_pBaseofDump==NULL)
{
OutMsg( _T("Failed to MapViewOfFile(0x%x) for 0x%x"),
m_hDumpMapFile,GetLastError() );
return E_FAIL;
}
pMdpHeader=(PMINIDUMP_HEADER)m_pBaseofDump;
if(pMdpHeader->Signature!=MINIDUMP_SIGNATURE)
{
OutMsg(_T("File [%s] is not a valid user dump [0x%x]."),
lpszFileName,pMdpHeader->Signature);
Close();
return E_FAIL;
}
GetFileSizeEx(m_hDumpFile,(PLARGE_INTEGER)&m_ulFileSize);
OutMsg(_T("File [%s] is mapped to 0x%x successfuly, size=%I64u"),
lpszFileName,m_pBaseofDump,m_ulFileSize);
strncpy(szSignature,(const char *)&(pMdpHeader->Signature),sizeof(ULONG32));
szSignature[sizeof(ULONG32)]=0;
OutMsg(_T("Header: Signature=%s(0x%x), Version=0x%x, Streams=%u,DirRva=0x%x"),
szSignature,pMdpHeader->Signature,
pMdpHeader->Version,
pMdpHeader->NumberOfStreams,
pMdpHeader->StreamDirectoryRva);
OutMsg(_T("Header: CheckSum=0x%x, Stamp=0x%x, Flags=0x%x"),
pMdpHeader->CheckSum,
pMdpHeader->TimeDateStamp,
pMdpHeader->Flags);
this->FillStreamList(hWndStreamList);
return S_OK;
}
主要用途使用WinDBG和Visual Studio 2005这样的现成工具都可以打开和分析转储文件。但是使用这些工具无法直接观察转出文件的内容,比如知道转储文件中到底有哪些数据流,每个数据流到底包含什么样的信息。而UdmpView可以弥补这个不足。第二,当我们编写代码来产生转储文件(使用MiniDumpWriteDumpStream)时,那么使用本工具可以很方便的查看写入的内容。另外,本工具可以帮助我们学习转储文件格式和了解转储文件API工作方法。 |
下载包含UdmpView.exe和一个示例性用户态转储文件的压缩包(~10KB) |