Stamp of Software Debugging
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
navigation bar seprate line
用户态转储文件观察器

简单地说,用户态转储文件(User Mode Dump)就是用于保存应用程序在某一时刻运行状态的二进制文件。为了支持调试,Windows系统定义了用户态转储文件的格式并提供了API来创建和读取用户态转储文件。与描述整个系统状态的系统转储文件相比,用户态转储文件的描述范围仅限于用户进程,二者的格式也是不同的。

在Windows的很多文档中,用户态转储文件被称为MiniDump,意思是小型的转储文件,但这个名字并不总是确切的,因为我们也可以产生包含完整内存数据的非常庞大的转储文件。

用户态转储文件(User Mode Dump)对于产品期调试、调试难以复现的随机问题和调试内存泄漏等问题都有有着重要价值。《软件调试》一书的第12.9节详细介绍了用户态转储文件的格式和用途以及分析方法。

UdmpView工具用来显示用户态转储文件中包含的各类数据流。既可以显示每种数据流的原始数据(Raw Data),也可以把固定类型的信息以结构化的形式显示出来。

使用方法

UdmpView程序的界面很简单(见下图),所有操作都列在左侧。右侧的两个列表框用来显示命令的执行结果。上面的列表框用来显示当前转储文件中所包含的所有数据流。下面的列表框用来显示数据流的详细内容或者命令的其它执行结果。各个命令按钮的功能如下:

  • Open...
  • 用于打开要观察的用户态转储文件,用户态转储文件通常是以.dmp为后缀。如果打开的是系统转储文件,那么UdmpView会在执行打开操作时提示错误。
  • Select All
  • 用于选择当前转储文件中的所有数据流,也就是右侧列表中的所有条目。如果你要选择单个或者部分条目,那么请使用鼠标单击要选择的条目。
  • Show
  • 显示选中数据流的内容。
  • Copy
  • 将右侧内容列表框的选中行复制到剪贴板(Clipboard)。
  • Copy All
  • 将右侧内容列表框中的所有信息复制到剪贴板(Clipboard)。
  • Clear
  • 清除右侧内容列表框中的所有信息。
  • Read Raw
  • 读取转储文件中的原始数据,使用此命令前,应该在该按钮上面的两个编辑框中分别输入要观察数据的相对地址(RVA)和长度。如果使用十六进制数,那么应该以0x开头。
  • Close File
  • 关闭当前观察的文件。
  • Quit
  • 退出本程序。

下图是使用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)UdmpView.zip

navigation bar seprate line
Copyright (C) 2008-2013 Raymond Zhang, All Rights Reserved