简介

在过去的几年中,崩溃转储成为我们调试活动的一个重要部分。当我们的软件在客户的机器出现故障时,创建应用程序状态的快照并使用在开发人员机器上运行的传统调试器对其进行分析的可能性是非常宝贵的。第一代崩溃转储(通常称为“完全用户转储”)捕获了整个进程虚拟内存的内容。尽管对于事后调试毫无疑问是有用的,但这样的转储常常变得如此巨大,以至于不可能或至少不方便将它们以电子方式传输给软件开发人员。此外,没有以编程方式创建此类转储的公共API,我们必须依赖外部工具(如Dr.Watson或Userdump)来创建它们。
一个新的崩溃转储系列,叫做“minidumps”,与Windows XP一起出现在我们面前。minidump是高度可定制的。在最流行的配置中,小型转储包含的信息刚好足以恢复失败进程中所有线程的调用堆栈,并在失败时检查本地变量的值。这种转储很小(通常只有几千字节),因此很容易以电子方式将它们传输给软件开发人员。但如果需要,小型转储可以包含比旧式崩溃转储更多的信息(例如,小型转储可以包含有关进程使用的内核对象的信息)。此外,可再发行的DbgHelp.dll公开了一个用于以编程方式创建小型转储的公共API,我们不再依赖外部工具。
小型转储的可定制性给我们带来了一个问题:我们需要多少关于应用程序状态的信息才能有效地进行调试,同时使小型转储尽可能小?虽然对调用堆栈和局部变量值的了解通常足以调试简单的访问冲突,但更困难的问题将需要额外的信息。例如,我们可能需要查看全局变量的值,检查堆的完整性,或者分析进程虚拟内存的布局。同时,如果可执行文件本身在开发人员的计算机上可用,则可执行模块的代码部分可能是多余的。
幸运的是,DbgHelp函数(MiniDumpWriteDump和MiniDumpCallback)提供了这样的控制级别,甚至更多。在本文中,我们将探讨如何使用这些函数来创建小转储,这些小转储虽然小,但仍然包含足够的信息,可以进行有效的调试。我们还将看到小型转储中可以包含哪些类型的数据,以及如何使用流行的调试器(WinDbg和VS.NET)来查看这些数据。

Minidump Types

让我们从一些代码开始。图1包含MiniDumpWriteDump函数的声明,图2显示了如何使用该函数创建一个简单的minidump。

 Figure 1:

BOOL MiniDumpWriteDump(
HANDLE hProcess,
DWORD ProcessId,
HANDLE hFile,
MINIDUMP_TYPE DumpType,
PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
PMINIDUMP_CALLBACK_INFORMATION CallbackParam
);

Figure
2:void CreateMiniDump( EXCEPTION_POINTERS*pep )
{
//Open the file HANDLE hFile= CreateFile( _T("MiniDump.dmp"), GENERIC_READ |GENERIC_WRITE,0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );if( ( hFile != NULL ) && ( hFile !=INVALID_HANDLE_VALUE ) )
{
//Create the minidump MINIDUMP_EXCEPTION_INFORMATION mdei;

mdei.ThreadId
=GetCurrentThreadId();
mdei.ExceptionPointers
=pep;
mdei.ClientPointers
=FALSE;

MINIDUMP_TYPE mdt
=MiniDumpNormal;

BOOL rv
=MiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(),
hFile, mdt, (pep
!= 0) ? &mdei : 0, 0, 0);if( !rv )
_tprintf( _T(
"MiniDumpWriteDump failed. Error: %u \n"), GetLastError() );else_tprintf( _T("Minidump created.\n") );//Close the file CloseHandle( hFile );

}
else{
_tprintf( _T(
"CreateFile failed. Error: %u \n"), GetLastError() );
}

}

标签: none

添加新评论