|
|
/*++
Copyright (c) 1994 Microsoft Corporation
Module Name:
bugdump.c
Abstract:
WinDbg Extension Api
Author:
David N. Cutler (davec) 6-Aug-1994
Environment:
User Mode.
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
#include "string.h"
//
// Declare storage for bug check dump buffer and component name.
//
#define BUFFER_SIZE (1 << 12)
#define NAME_SIZE (1 << 5)
ULONG DumpBuffer[BUFFER_SIZE / sizeof(ULONG)]; UCHAR NameBuffer[NAME_SIZE + 1];
DECLARE_API( bugdump )
/*++
Routine Description:
Dump bug check callback data.
Arguments:
arg - Supplies the optional component name.
Return Value:
None.
--*/
{
ULONG64 CallbackAddress; ULONG64 ComponentAddress; PUCHAR ComponentName; ULONG DataLength; PUCHAR DumpState; ULONG Limit; ULONG64 ListHead; ULONG Index; ULONG Inner; ULONG64 NextEntry; ULONG Result, Offset;
//
// If a componetn name name is specified, then only dump that components
// data. Otherwise, dump the components data for all components that are
// recorded in the bug check call back list.
//
if (args[0] != '\0') { ComponentName = (PUCHAR)&args[0];
} else { ComponentName = NULL; }
//
// Get the address and contents of the bug check callback listhead.
//
dprintf("**** Dump of Bug Check Data ****\n"); ListHead = GetNtDebuggerData(KeBugCheckCallbackListHead); if ((ListHead == 0) || GetFieldValue(ListHead, "nt!_LIST_ENTRY", "Flink", NextEntry)) {
//
// The target build does not bug check callbacks.
//
dprintf("%08p: No bug check callback data available\n", ListHead);
} else {
GetFieldOffset("nt!_KBUGCHECK_CALLBACK_RECORD", "Entry", &Offset);
//
// Dump the specified bug check callback data.
//
while (NextEntry != ListHead) {
//
// Compute the address of the next callback record and read it.
//
CallbackAddress = NextEntry - Offset;
if (GetFieldValue(CallbackAddress, "nt!_KBUGCHECK_CALLBACK_RECORD", "Entry.Flink", NextEntry)) {
//
// The target callback record could not be read.
//
dprintf("%08p: Bug check callback record could not be read\n", CallbackAddress);
break;
} else { ULONG State;
//
// Set the address of struct to be read
//
InitTypeRead(CallbackAddress, nt!_KBUGCHECK_CALLBACK_RECORD);
//
// Read the component name.
//
ComponentAddress = ReadField(Component);
for (Index = 0; Index < NAME_SIZE; Index += 1) { if (ReadMemory(ComponentAddress, &NameBuffer[Index], sizeof(UCHAR), &Result) == FALSE) {
NameBuffer[Index] = '\0'; }
ComponentAddress += 1; if (NameBuffer[Index] == '\0') { break; } }
NameBuffer[Index] = '\0';
//
// If a component name is specified, then compare the
// component with the specified name. If the component
// name does not match, then continue with the next
// entry in the list.
//
if (ComponentName != NULL) { if (_stricmp(ComponentName, &NameBuffer[0]) != 0) { continue; } }
//
// Either all bug callback records are being dumped or the
// specified component has been found. Dump the contents of
// the dump buffer, if the state of the callback record is
// not inserted.
//
dprintf(" Dumping data for component %s \n", &NameBuffer[0]); State = (ULONG) ReadField(State); if (State == BufferInserted) { dprintf(" No bug check dump data available\n\n");
} else { if (State == BufferStarted) { DumpState = "Dump started/not finished";
} else if (State == BufferFinished) { DumpState = "Dump started/finished";
} else { DumpState = "Dump started/not completed"; }
dprintf(" Buffer state - %s\n\n", DumpState); DataLength = (ULONG) ReadField(Length); if (DataLength > BUFFER_SIZE) { DataLength = BUFFER_SIZE; }
RtlZeroMemory(&DumpBuffer[0], BUFFER_SIZE); if (ReadMemory(ReadField(Buffer), &DumpBuffer[0], DataLength, &Result) == FALSE) {
dprintf("%08lx: Bug check dump data could not be read\n", Result);
} else {
//
// Display bug check data.
//
DataLength = (DataLength + sizeof(ULONG) - 1) / sizeof(ULONG); for (Index = 0; Index < DataLength; Index += 4) { dprintf("%08lx", Index * 4); Limit = Index + 4; if (Limit > DataLength) { Limit = DataLength; }
for (Inner = Index; Inner < Limit; Inner += 1) { dprintf(" %08lx", DumpBuffer[Inner]); }
dprintf("\n"); }
dprintf("\n"); } }
if (ComponentName != NULL) { break; } } } }
return S_OK; }
|