📄 dwdmpgen.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
#include <bldver.h>
#include "osaxs_p.h"
//#include "kdp.h"
// Nkshx.h defines these, so get rid of them before including DwCeDump.h
#ifdef ProcessorLevel
#undef ProcessorLevel
#endif
#ifdef ProcessorRevision
#undef ProcessorRevision
#endif
#include "DwCeDump.h"
#define WATSON_BINARY_DUMP TRUE
#include "DwPublic.h"
#include "DwPrivate.h"
#include "DwDmpGen.h"
#define STACK_FRAMES_BUFFERED 20
#define MAX_STREAMS (ceStreamBucketParameters - ceStreamNull)
#define DISABLEFAULTS() (UTlsPtr()[TLSSLOT_KERNEL] |= (TLSKERN_NOFAULTMSG|TLSKERN_NOFAULT))
#define ENABLEFAULTS() (UTlsPtr()[TLSSLOT_KERNEL] &= ~(TLSKERN_NOFAULTMSG|TLSKERN_NOFAULT))
#define SET_FRAME_COUNT(ThreadCount, FrameCount) \
{if (ThreadCount < dwMaxThreadEntries) (*((WORD*)g_bBuffer + ThreadCount) = (WORD)FrameCount);}
#define CHECK_FRAME_COUNT(ThreadCount, FrameCount) \
((ThreadCount < dwMaxThreadEntries) ? (*((WORD*)g_bBuffer + ThreadCount) == (WORD)FrameCount) : TRUE)
#define GET_FRAME_COUNT(ThreadCount) \
((ThreadCount < dwMaxThreadEntries) ? (*((WORD*)g_bBuffer + ThreadCount)) : -1)
#define VIRTUAL_MEMORY TRUE
#define PHYSICAL_MEMORY FALSE
typedef struct _MEMORY_BLOCK
{
DWORD dwMemoryStart;
DWORD dwMemorySize;
} MEMORY_BLOCK;
MINIDUMP_HEADER g_ceDmpHeader;
MINIDUMP_DIRECTORY g_ceDmpDirectory[MAX_STREAMS];
CEDUMP_SYSTEM_INFO g_ceDmpSystemInfo;
CEDUMP_EXCEPTION_STREAM g_ceDmpExceptionStream;
CEDUMP_EXCEPTION g_ceDmpException;
CEDUMP_ELEMENT_LIST g_ceDmpExceptionContext;
CEDUMP_ELEMENT_LIST g_ceDmpModuleList;
CEDUMP_ELEMENT_LIST g_ceDmpProcessList;
CEDUMP_ELEMENT_LIST g_ceDmpThreadList;
CEDUMP_ELEMENT_LIST g_ceDmpThreadContextList;
CEDUMP_THREAD_CALL_STACK_LIST g_ceDmpThreadCallStackList;
CEDUMP_MEMORY_LIST g_ceDmpMemoryVirtualList;
CEDUMP_MEMORY_LIST g_ceDmpMemoryPhysicalList;
CEDUMP_BUCKET_PARAMETERS g_ceDmpBucketParameters;
WATSON_DUMP_SETTINGS g_watsonDumpSettings = {0};
BYTE g_bBuffer[FLEX_PTMI_BUFFER_SIZE];
MEMORY_BLOCK g_memoryVirtualBlocks[MAX_MEMORY_VIRTUAL_BLOCKS];
DWORD g_dwMemoryVirtualBlocksTotal = 0;
DWORD g_dwMemoryVirtualSizeTotal = 0;
MEMORY_BLOCK g_memoryPhysicalBlocks[MAX_MEMORY_PHYSICAL_BLOCKS];
DWORD g_dwMemoryPhysicalBlocksTotal = 0;
DWORD g_dwMemoryPhysicalSizeTotal = 0;
BYTE g_bBufferAlignment[CEDUMP_ALIGNMENT] = {0};
DWORD g_dwReservedMemorySize = 0;
DWORD g_dwWrittenOffset;
DWORD g_dwWrittenCRC;
DWORD g_dwReadOffset;
DWORD g_dwReadCRC;
LONG g_lThreadsInPostMortemCapture = 0;
BOOL g_fDumpHeapData = FALSE;
BOOL g_fDumpNkGlobals = FALSE;
BOOL g_fNkGlobalsDumped = FALSE;
BOOL g_fCaptureDumpFileOnDeviceCalled = FALSE;
BOOL g_fReportFaultCalled = FALSE;
DWORD g_dwLastError;
BOOL g_fFirstChanceException;
PTHREAD g_pDmpThread = NULL;
PPROCESS g_pDmpProc = NULL;
PEXCEPTION_RECORD g_pExceptionRecord = NULL;
PCONTEXT g_pContextException = NULL;
HANDLE g_hEventDumpFileReady = NULL;
WCHAR g_wzOEMString[MAX_PATH];
DWORD g_dwOEMStringSize = 0;
WCHAR g_wzPlatformType[MAX_PATH];
DWORD g_dwPlatformTypeSize = 0;
PLATFORMVERSION g_platformVersion[4];
DWORD g_dwPlatformVersionSize = 0;
typedef struct VERHEAD
{
WORD wTotLen;
WORD wValLen;
WORD wType; /* always 0 */
WCHAR szKey[(sizeof("VS_VERSION_INFO")+3)&~03];
VS_FIXEDFILEINFO vsf;
} VERHEAD ;
typedef struct resroot_t
{
DWORD flags;
DWORD timestamp;
DWORD version;
WORD numnameents;
WORD numidents;
} resroot_t;
typedef struct resent_t
{
DWORD id;
DWORD rva;
} resent_t;
typedef struct resdata_t
{
DWORD rva;
DWORD size;
DWORD codepage;
DWORD unused;
} resdata_t;
#define DWORDUP(x) (((x)+3)&~03)
BOOL WINAPI EventModify(HANDLE hEvent, DWORD func)
{
// Used by SetEvent, ResetEvent, and PulseEvent
return g_OsaxsData.pEventModify(hEvent, func);
}
VOID* GetObjectPtrByType(HANDLE h, int type)
{
return g_OsaxsData.pfnGetObjectPtrByType(h, type);
}
/*----------------------------------------------------------------------------
WatsonReadData
Reads data from the input stream, either reserved memory or KDBG.
----------------------------------------------------------------------------*/
HRESULT WatsonReadData(DWORD dwOffset, PVOID pDataBuffer, DWORD dwDataSize, BOOL fCalculateCRC)
{
HRESULT hRes = E_FAIL;
DWORD dwCRCLoop;
DEBUGGERMSG(OXZONE_DWDMPGEN,(L"++DwDmpGen!WatsonReadData: Enter\r\n"));
KD_ASSERT((dwOffset + dwDataSize) <= g_dwReservedMemorySize);
if ((dwOffset + dwDataSize) > g_dwReservedMemorySize)
{
DEBUGGERMSG(OXZONE_ALERT,(L" DwDmpGen!WatsonReadData: Trying to read beyond size of reserved memory, Reserved Size=0x%08X, dwOffset=0x%08X, dwDataSize=0x%08X\r\n", g_dwReservedMemorySize, dwOffset, dwDataSize));
hRes = E_OUTOFMEMORY;
goto Exit;
}
if (pfnNKKernelLibIoControl((HANDLE) KMOD_CORE, IOCTL_KLIB_READWATSON, NULL, dwOffset, pDataBuffer, dwDataSize, NULL) != dwDataSize)
{
DEBUGGERMSG(OXZONE_ALERT,(L" DwDmpGen!WatsonReadData: KernelLibIoControl failed, pDataBuffer=0x%08X, dwOffset=0x%08X, dwDataSize=0x%08X\r\n", pDataBuffer, dwOffset, dwDataSize));
hRes = E_FAIL;
goto Exit;
}
if (fCalculateCRC)
{
// Make sure we are reading in sequentially
KD_ASSERT(g_dwReadOffset == dwOffset);
if (g_dwReadOffset != dwOffset)
{
DEBUGGERMSG(OXZONE_ALERT,(L" DwDmpGen!WatsonReadData: Dump file not read sequentially, Expected Offset=%u, Actual Offset=%u\r\n", g_dwReadOffset, dwOffset));
hRes = E_FAIL;
goto Exit;
}
for (dwCRCLoop = 0; dwCRCLoop < dwDataSize; ++dwCRCLoop)
{
// Add up all the bytes in the dump file (Simple CRC)
g_dwReadCRC += *((BYTE *)pDataBuffer + dwCRCLoop);
}
g_dwReadOffset += dwDataSize;
}
hRes = S_OK;
Exit:
DEBUGGERMSG(OXZONE_DWDMPGEN,(L"--DwDmpGen!WatsonReadData: Leave, hRes=0x%08X\r\n", hRes));
return hRes;
}
/*----------------------------------------------------------------------------
WatsonWriteData
Writes the data to the output stream, either reserved memory or KDBG.
----------------------------------------------------------------------------*/
HRESULT WatsonWriteData(DWORD dwOffset, PVOID pDataBuffer, DWORD dwDataSize, BOOL fCalculateCRC)
{
HRESULT hRes = E_FAIL;
DWORD dwWriteLoop;
BYTE bDataOut;
BOOL fExceptionEncountered = FALSE;
DWORD dwWriteLoopError;
DWORD dwExceptionCount = 0;
PVOID pAddr;
if ((dwOffset + dwDataSize) > g_dwReservedMemorySize)
{
DEBUGGERMSG(OXZONE_ALERT, (L" DwDmpGen!WatsonWriteData: Trying to write beyond size of reserved memory, Reserved Size=0x%08X, dwOffset=0x%08X, dwDataSize=0x%08X\r\n", g_dwReservedMemorySize, dwOffset, dwDataSize));
hRes = E_OUTOFMEMORY;
goto Exit;
}
if (fCalculateCRC)
{
// Make sure we are writing out sequentially
KD_ASSERT(g_dwWrittenOffset == dwOffset);
if (g_dwWrittenOffset != dwOffset)
{
DEBUGGERMSG(OXZONE_ALERT, (L" DwDmpGen!WatsonWriteData: Data not written sequentially, Expected Offset=%u, Actual Offset=%u\r\n", g_dwWrittenOffset, dwOffset));
hRes = E_FAIL;
goto Exit;
}
g_dwWrittenOffset += dwDataSize;
}
for (dwWriteLoop = 0; dwWriteLoop < dwDataSize; ++dwWriteLoop)
{
pAddr = (PVOID)((BYTE *)pDataBuffer + dwWriteLoop);
#ifdef DEBUG
// At this point we should only have valid addresses that are currently paged in
if ((0 == dwWriteLoop) || ((DWORD)pAddr & (PAGE_SIZE-1)))
{
// Validate the page is paged in each time we move to a new page
KD_ASSERT(NULL != SafeDbgVerify(pAddr, TRUE /* Probe Only */));
}
#endif // DEBUG
// Just in case we may be reading from invalid memory, catch possible exceptions
// Prevent hitting exceptions in the debugger
DISABLEFAULTS();
__try
{
bDataOut = *((BYTE *)pAddr);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
if (FALSE == fExceptionEncountered)
{
dwWriteLoopError = dwWriteLoop;
fExceptionEncountered = TRUE;
}
bDataOut = 0;
++ dwExceptionCount;
}
// Enable hitting exceptions in the debugger
ENABLEFAULTS();
// Write out byte of memory
if (pfnNKKernelLibIoControl((HANDLE) KMOD_CORE, IOCTL_KLIB_WRITEWATSON, &bDataOut, 1, NULL, (dwOffset+dwWriteLoop), NULL) != 1)
{
DEBUGGERMSG(OXZONE_ALERT, (L" DwDmpGen!WatsonWriteData: KernelLibIoControl failed, pDataBuffer=0x%08X, dwOffset=0x%08X, dwWriteLoop=0x%08X\r\n", pDataBuffer, dwOffset, dwWriteLoop));
hRes = E_FAIL;
goto Exit;
}
if (fCalculateCRC)
{
// Add up all the bytes written so far (Simple CRC)
g_dwWrittenCRC += bDataOut;
}
}
if (TRUE == fExceptionEncountered)
{
// This is not an error, just a warning (We should try avoid reading invalid memory)
DEBUGGERMSG(OXZONE_ALERT, (L" DwDmpGen!WatsonWriteData: Exception encountered while reading memory, pDataBuffer=0x%08X, First Exception Offset=0x%08X, Exception Count=%u\r\n",
pDataBuffer, dwWriteLoopError, dwExceptionCount));
}
hRes = S_OK;
Exit:
return hRes;
}
//------------------------------------------------------------------------------
// Find type entry by number
//------------------------------------------------------------------------------
DWORD FindTypeByNum(LPBYTE curr, DWORD id)
{
DWORD dwRva = 0;
resroot_t *rootptr;
resent_t *resptr;
int count;
DEBUGGERMSG(OXZONE_DWDMPGEN,(L"++DwDmpGen!FindTypeByNum: Enter\r\n"));
rootptr = (resroot_t *)curr;
resptr = (resent_t *)(curr + sizeof(resroot_t) +
rootptr->numnameents*sizeof(resent_t));
count = rootptr->numidents;
while (count--)
{
if (!id || (resptr->id == id))
{
KD_ASSERT (!IsSecureVa(resptr->rva));
dwRva = resptr->rva;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -