DUMP.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:10k
源码类别:
Windows编程
开发平台:
Visual C++
- /*++
- Copyright (c) 1993 Microsoft Corporation
- Module Name:
- dump.c
- Abstract:
- This file implements the crash dump code.
- Author:
- Wesley Witt (wesw) 27-Jan-1995
- Environment:
- User Mode
- --*/
- #include <windows.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <stddef.h>
- #include <crash.h>
- #include "drwatson.h"
- #include "proto.h"
- #include "messages.h"
- #include "resource.h"
- #define MEM_SIZE (64*1024)
- //
- // these are here only so that we can link
- // with crashlib. they are only referenced
- // when reading a kernel mode crash dump
- //
- DWORD KiProcessors;
- DWORD KiPcrBaseAddress;
- //
- // private data structure use for communcating
- // crash dump data to the callback function
- //
- typedef struct _CRASH_DUMP_INFO {
- PDEBUGPACKET dp;
- EXCEPTION_DEBUG_INFO *ExceptionInfo;
- DWORD MemoryCount;
- DWORD Address;
- PUCHAR MemoryData;
- MEMORY_BASIC_INFORMATION mbi;
- BOOL MbiOffset;
- ULONG MbiRemaining;
- PTHREADCONTEXT ptctx;
- IMAGEHLP_MODULE mi;
- PCRASH_MODULE CrashModule;
- } CRASH_DUMP_INFO, *PCRASH_DUMP_INFO;
- LPSTR
- ExpandPath(
- LPSTR lpPath
- );
- DWORD
- GetTeb(
- HANDLE hTread
- );
- BOOL
- CrashDumpCallback(
- DWORD DataType,
- PVOID *DumpData,
- LPDWORD DumpDataLength,
- PCRASH_DUMP_INFO CrashdumpInfo
- )
- /*++
- Routine Description:
- This function is the callback used by crashlib.
- Its purpose is to provide data to DmpCreateUserDump()
- for writting to the crashdump file.
- Arguments:
- DataType - requested data type
- DumpData - pointer to a pointer to the data
- DumpDataLength - pointer to the data length
- CrashdumpInfo - DrWatson private data
- Return Value:
- TRUE - continue calling back for the requested data type
- FALSE - stop calling back and go on to the next data type
- --*/
- {
- DWORD cb;
- switch( DataType ) {
- case DMP_DEBUG_EVENT:
- *DumpData = &CrashdumpInfo->dp->DebugEvent;
- *DumpDataLength = sizeof(DEBUG_EVENT);
- break;
- case DMP_THREAD_STATE:
- {
- static CRASH_THREAD CrashThread;
- PTHREADCONTEXT ptctx;
- PLIST_ENTRY ListEntry;
- *DumpData = &CrashThread;
- if (CrashdumpInfo->ptctx == NULL) {
- ListEntry = CrashdumpInfo->dp->ThreadList.Flink;
- } else {
- ListEntry = CrashdumpInfo->ptctx->ThreadList.Flink;
- }
- if (ListEntry == &CrashdumpInfo->dp->ThreadList) {
- CrashdumpInfo->ptctx = NULL;
- return FALSE;
- }
- ptctx =
- CrashdumpInfo->ptctx = CONTAINING_RECORD(ListEntry, THREADCONTEXT, ThreadList);
- ZeroMemory(&CrashThread, sizeof(CrashThread));
- CrashThread.ThreadId = ptctx->dwThreadId;
- CrashThread.SuspendCount = SuspendThread(ptctx->hThread);
- if (CrashThread.SuspendCount != (DWORD)-1) {
- ResumeThread(ptctx->hThread);
- }
- CrashThread.PriorityClass = GetPriorityClass(CrashdumpInfo->dp->hProcess);
- CrashThread.Priority = GetThreadPriority(ptctx->hThread);
- CrashThread.Teb = GetTeb(ptctx->hThread);
- *DumpDataLength = sizeof(CRASH_THREAD);
- }
- break;
- case DMP_MEMORY_BASIC_INFORMATION:
- while( TRUE ) {
- CrashdumpInfo->Address += CrashdumpInfo->mbi.RegionSize;
- if (!VirtualQueryEx(
- CrashdumpInfo->dp->hProcess,
- (LPVOID)CrashdumpInfo->Address,
- &CrashdumpInfo->mbi,
- sizeof(MEMORY_BASIC_INFORMATION) )) {
- return FALSE;
- }
- if ((CrashdumpInfo->mbi.AllocationProtect & PAGE_GUARD) ||
- (CrashdumpInfo->mbi.AllocationProtect & PAGE_NOACCESS)) {
- continue;
- }
- if ((CrashdumpInfo->mbi.State & MEM_FREE) ||
- (CrashdumpInfo->mbi.State & MEM_RESERVE)) {
- continue;
- }
- break;
- }
- *DumpData = &CrashdumpInfo->mbi;
- *DumpDataLength = sizeof(MEMORY_BASIC_INFORMATION);
- break;
- case DMP_THREAD_CONTEXT:
- {
- PLIST_ENTRY ListEntry;
- if (CrashdumpInfo->ptctx == NULL) {
- ListEntry = CrashdumpInfo->dp->ThreadList.Flink;
- } else {
- ListEntry = CrashdumpInfo->ptctx->ThreadList.Flink;
- }
- if (ListEntry == &CrashdumpInfo->dp->ThreadList) {
- CrashdumpInfo->ptctx = NULL;
- return FALSE;
- }
- CrashdumpInfo->ptctx = CONTAINING_RECORD(ListEntry, THREADCONTEXT, ThreadList);
- *DumpData = &CrashdumpInfo->ptctx->context;
- *DumpDataLength = sizeof(CONTEXT);
- }
- break;
- case DMP_MODULE:
- if (CrashdumpInfo->mi.BaseOfImage == 0) {
- return FALSE;
- }
- CrashdumpInfo->CrashModule->BaseOfImage = CrashdumpInfo->mi.BaseOfImage;
- CrashdumpInfo->CrashModule->SizeOfImage = CrashdumpInfo->mi.ImageSize;
- CrashdumpInfo->CrashModule->ImageNameLength = strlen(CrashdumpInfo->mi.ImageName) + 1;
- strcpy( CrashdumpInfo->CrashModule->ImageName, CrashdumpInfo->mi.ImageName );
- *DumpData = CrashdumpInfo->CrashModule;
- *DumpDataLength = sizeof(CRASH_MODULE) + CrashdumpInfo->CrashModule->ImageNameLength;
- if (!SymGetModuleInfo( CrashdumpInfo->dp->hProcess, (DWORD)-1, &CrashdumpInfo->mi )) {
- CrashdumpInfo->mi.BaseOfImage = 0;
- }
- break;
- case DMP_MEMORY_DATA:
- if (!CrashdumpInfo->MemoryCount) {
- CrashdumpInfo->Address = 0;
- CrashdumpInfo->MbiOffset = 0;
- CrashdumpInfo->MbiRemaining = 0;
- ZeroMemory( &CrashdumpInfo->mbi, sizeof(MEMORY_BASIC_INFORMATION) );
- CrashdumpInfo->MemoryData = VirtualAlloc(
- NULL,
- MEM_SIZE,
- MEM_COMMIT,
- PAGE_READWRITE
- );
- }
- if (!CrashdumpInfo->MbiRemaining) {
- while( TRUE ) {
- CrashdumpInfo->Address += CrashdumpInfo->mbi.RegionSize;
- if (!VirtualQueryEx(
- CrashdumpInfo->dp->hProcess,
- (LPVOID)CrashdumpInfo->Address,
- &CrashdumpInfo->mbi,
- sizeof(MEMORY_BASIC_INFORMATION) )) {
- if (CrashdumpInfo->MemoryData) {
- VirtualFree( CrashdumpInfo->MemoryData, MEM_SIZE, MEM_RELEASE );
- }
- return FALSE;
- }
- if ((CrashdumpInfo->mbi.Protect & PAGE_GUARD) ||
- (CrashdumpInfo->mbi.Protect & PAGE_NOACCESS)) {
- continue;
- }
- if ((CrashdumpInfo->mbi.State & MEM_FREE) ||
- (CrashdumpInfo->mbi.State & MEM_RESERVE)) {
- continue;
- }
- CrashdumpInfo->MbiOffset = 0;
- CrashdumpInfo->MbiRemaining = CrashdumpInfo->mbi.RegionSize;
- CrashdumpInfo->MemoryCount += 1;
- break;
- }
- }
- *DumpDataLength = min( CrashdumpInfo->MbiRemaining, MEM_SIZE );
- CrashdumpInfo->MbiRemaining -= *DumpDataLength;
- ReadProcessMemory(
- CrashdumpInfo->dp->hProcess,
- (PUCHAR)((ULONG)CrashdumpInfo->mbi.BaseAddress + (ULONG)CrashdumpInfo->MbiOffset),
- CrashdumpInfo->MemoryData,
- *DumpDataLength,
- &cb
- );
- *DumpData = CrashdumpInfo->MemoryData;
- CrashdumpInfo->MbiOffset += *DumpDataLength;
- break;
- }
- return TRUE;
- }
- BOOL
- CreateDumpFile(
- PDEBUGPACKET dp,
- LPEXCEPTION_DEBUG_INFO ed
- )
- /*++
- Routine Description:
- This function creates a crash dump file.
- Arguments:
- dp - debug packet for current process
- ed - exception data
- Return Value:
- TRUE - Crash dump was created
- FALSE - Crash dump was NOT created
- --*/
- {
- CRASH_DUMP_INFO CrashdumpInfo;
- LPSTR p;
- ZeroMemory( &CrashdumpInfo, sizeof(CRASH_DUMP_INFO) );
- CrashdumpInfo.dp = dp;
- CrashdumpInfo.ExceptionInfo = ed;
- CrashdumpInfo.ptctx = NULL;
- //
- // Get first entry in module list
- //
- SymGetModuleInfo( dp->hProcess, (DWORD)0, &CrashdumpInfo.mi );
- CrashdumpInfo.CrashModule = LocalAlloc( LPTR, 4096 );
- p = ExpandPath( dp->options.szCrashDump );
- if (!p) {
- return FALSE;
- }
- DmpCreateUserDump( p, CrashDumpCallback, &CrashdumpInfo );
- free( p );
- LocalFree( CrashdumpInfo.CrashModule );
- return TRUE;
- }