mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
249 lines
6.6 KiB
249 lines
6.6 KiB
/*++
|
|
|
|
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.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PKBUGCHECK_CALLBACK_RECORD CallbackAddress;
|
|
KBUGCHECK_CALLBACK_RECORD CallbackRecord;
|
|
PUCHAR ComponentAddress;
|
|
PUCHAR ComponentName;
|
|
ULONG DataLength;
|
|
PUCHAR DumpState;
|
|
ULONG Limit;
|
|
LIST_ENTRY ListEntry;
|
|
ULONG ListHead;
|
|
ULONG Index;
|
|
ULONG Inner;
|
|
PLIST_ENTRY NextEntry;
|
|
ULONG Result;
|
|
|
|
//
|
|
// 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 = GetExpression("KeBugCheckCallbackListHead");
|
|
if ((ListHead == 0) ||
|
|
(ReadMemory((DWORD)ListHead,
|
|
&ListEntry,
|
|
sizeof(LIST_ENTRY),
|
|
&Result) == FALSE)) {
|
|
|
|
//
|
|
// The target build does not bug check callbacks.
|
|
//
|
|
|
|
dprintf("%08lx: No bug check callback data available\n", Result);
|
|
|
|
} else {
|
|
|
|
//
|
|
// Dump the specified bug check callback data.
|
|
//
|
|
|
|
NextEntry = ListEntry.Flink;
|
|
while (NextEntry != (PLIST_ENTRY)ListHead) {
|
|
|
|
//
|
|
// Compute the address of the next callback record and read it.
|
|
//
|
|
|
|
CallbackAddress = CONTAINING_RECORD(NextEntry,
|
|
KBUGCHECK_CALLBACK_RECORD,
|
|
Entry);
|
|
|
|
if (ReadMemory((DWORD)CallbackAddress,
|
|
&CallbackRecord,
|
|
sizeof(KBUGCHECK_CALLBACK_RECORD),
|
|
&Result) == FALSE) {
|
|
|
|
//
|
|
// The target callback record could not be read.
|
|
//
|
|
|
|
dprintf("%08lx: Bug check callback record could not be read\n",
|
|
Result);
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Set the address of next entry in the callback list.
|
|
//
|
|
|
|
NextEntry = CallbackRecord.Entry.Flink;
|
|
|
|
//
|
|
// Read the component name.
|
|
//
|
|
|
|
ComponentAddress = CallbackRecord.Component;
|
|
for (Index = 0; Index < NAME_SIZE; Index += 1) {
|
|
if (ReadMemory((DWORD)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]);
|
|
if (CallbackRecord.State == BufferInserted) {
|
|
dprintf(" No bug check dump data available\n\n");
|
|
|
|
} else {
|
|
if (CallbackRecord.State == BufferStarted) {
|
|
DumpState = "Dump started/not finished";
|
|
|
|
} else if (CallbackRecord.State == BufferFinished) {
|
|
DumpState = "Dump started/finished";
|
|
|
|
} else {
|
|
DumpState = "Dump started/not completed";
|
|
}
|
|
|
|
dprintf(" Buffer state - %s\n\n", DumpState);
|
|
DataLength = CallbackRecord.Length;
|
|
if (DataLength > BUFFER_SIZE) {
|
|
DataLength = BUFFER_SIZE;
|
|
}
|
|
|
|
RtlZeroMemory(&DumpBuffer[0], BUFFER_SIZE);
|
|
if (ReadMemory((DWORD)CallbackRecord.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;
|
|
}
|