test: ppc/dmpstate.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# dmpstate.c File Reference

`#include "ki.h"`

Go to the source code of this file.

## Defines

#define | STAKWALK 8

## Functions

VOID | KiDisplayString (IN ULONG Column, IN ULONG Row, IN PCHAR Buffer)
PRUNTIME_FUNCTION | KiLookupFunctionEntry (IN ULONG ControlPc)
PVOID | KiPcToFileHeader (IN PVOID PcValue, OUT PVOID *BaseOfImage, OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry)
VOID | KeDumpMachineState (IN PKPROCESSOR_STATE ProcessorState, IN PCHAR Buffer, IN PULONG BugCheckParameters, IN ULONG NumberOfParameters, IN PKE_BUGCHECK_UNICODE_TO_ANSI UnicodeToAnsiRoutine)

## Variables

LIST_ENTRY | PsLoadedModuleList

## Define Documentation

#define STAKWALK 8

| Referenced by KeDumpMachineState().

## Function Documentation

VOID KeDumpMachineState | ( | IN PKPROCESSOR_STATE | ProcessorState,
|  | IN PCHAR | Buffer,
|  | IN PULONG | BugCheckParameters,
|  | IN ULONG | NumberOfParameters,
|  | IN PKE_BUGCHECK_UNICODE_TO_ANSI | UnicodeToAnsiRoutine
| ) |

Definition at line 67 of file ppc/dmpstate.c.

References Buffer, FALSE, HalDisableSystemInterrupt(), HalDisplayString(), HalQueryDisplayParameters(), HalSetDisplayParameters(), HIGH_LEVEL, Index, KdInitSystem(), KeGetCurrentThread, KeLoaderBlock, KiDisplayString(), KiLookupFunctionEntry(), KiPcToFileHeader(), L, _LOADER_PARAMETER_BLOCK::LoadOrderListHead, MmDbgReadCheck(), NtBuildNumber, NULL, PsLoadedModuleList, RtlImageNtHeader(), RtlVirtualUnwind(), sprintf(), and STAKWALK.

    00077                    :
    00078
    00079     This function formats and displays the machine state at the time of the
    00080     to bug check.
    00081
    00082 Arguments:
    00083
    00084     ProcessorState - Supplies a pointer to a processor state record.
    00085
    00086     Buffer - Supplies a pointer to a buffer to be used to output machine
    00087         state information.
    00088
    00089     BugCheckParameters - Supplies a pointer to an array of additional
    00090         bug check information.
    00091
    00092     NumberOfParameters - Suppiles the size of the bug check parameters
    00093         array.
    00094
    00095     UnicodeToAnsiRoutine - Supplies a pointer to a routine to convert Unicode strings
    00096         to Ansi strings without touching paged translation tables.
    00097
    00098 Return Value:
    00099
    00100     None.
    00101
    00102 --*/
    00103
    00104 {
    00105
    00106     PCONTEXT ContextRecord;
    00107     ULONG ControlPc;
    00108     PLDR_DATA_TABLE_ENTRY DataTableEntry;
    00109     ULONG DisplayColumn;
    00110     ULONG DisplayHeight;
    00111     ULONG DisplayRow;
    00112     ULONG DisplayWidth;
    00113     UNICODE_STRING DllName;
    00114     ULONG EstablisherFrame;
    00115     PRUNTIME_FUNCTION FunctionEntry;
    00116     PVOID ImageBase;
    00117     ULONG Index;
    00118     BOOLEAN InFunction;
    00119     ULONG LastStack;
    00120     PLIST_ENTRY ModuleListHead;
    00121     PLIST_ENTRY NextEntry;
    00122     ULONG NextPc;
    00123     ULONG StackLimit;
    00124     UCHAR AnsiBuffer[ 32 ];
    00125     ULONG DateStamp;
    00126
    00127     //
    00128     // Call the HAL to force all external interrupts to be disabled
    00129     // at the interrupt controller. PowerPC optimization does not
    00130     // do this when raising to high level.
    00131     //
    00132     for (Index = 0; Index < MAXIMUM_VECTOR; Index++) {
    00133        HalDisableSystemInterrupt(Index, HIGH_LEVEL);
    00134     }
    00135
    00136     //
    00137     // Query display parameters.
    00138     //
    00139
    00140     HalQueryDisplayParameters(&DisplayWidth,
    00141                               &DisplayHeight,
    00142                               &DisplayColumn,
    00143                               &DisplayRow);
    00144
    00145     //
    00146     // Display any addresses that fall within the range of any module in
    00147     // the loaded module list.
    00148     //
    00149
    00150     for (Index = 0; Index < NumberOfParameters; Index += 1) {
    00151         ImageBase = KiPcToFileHeader((PVOID)*BugCheckParameters,
    00152                                      &ImageBase,
    00153                                      &DataTableEntry);
    00154
    00155         if (ImageBase != NULL) {
    00156             sprintf(Buffer,
    00157                     "*** %08lX has base at %08lX - %s\n",
    00158                     *BugCheckParameters,
    00159                     ImageBase,
    00160                     (*UnicodeToAnsiRoutine)( &DataTableEntry->BaseDllName, AnsiBuffer, sizeof( AnsiBuffer )));
    00161
    00162             HalDisplayString(Buffer);
    00163         }
    00164
    00165         BugCheckParameters += 1;
    00166     }
    00167
    00168     //
    00169     // Virtually unwind to the caller of bug check.
    00170     //
    00171
    00172     ContextRecord = &ProcessorState->ContextFrame;
    00173     LastStack = ContextRecord->Gpr1;
    00174     ControlPc = ContextRecord->Lr - 4;
    00175     NextPc = ControlPc;
    00176     FunctionEntry = KiLookupFunctionEntry(ControlPc);
    00177     if (FunctionEntry != NULL) {
    00178         NextPc = RtlVirtualUnwind(ControlPc,
    00179                                   FunctionEntry,
    00180                                   ContextRecord,
    00181                                   &InFunction,
    00182                                   &EstablisherFrame,
    00183                                   NULL,
    00184                                   0,
    00185                                   0xffffffff);
    00186     }
    00187
    00188     //
    00189     // At this point the context record contains the machine state at the
    00190     // call to bug check.
    00191     //
    00192     // Put out the machine state at the time of the bugcheck.
    00193     //
    00194
    00195     sprintf(Buffer,
    00196             "\n Machine State at Call to Bug Check    IAR:%08lX MSR:%08lX\n",
    00197             ContextRecord->Lr,
    00198             ContextRecord->Msr);
    00199
    00200     HalDisplayString(Buffer);
    00201
    00202     //
    00203     // Format and output the integer registers.
    00204     //
    00205
    00206     sprintf(Buffer,
    00207             " R0:%8lX  R1:%8lX  R2:%8lX  R3:%8lX  R4:%8lX  R5:%8lX\n",
    00208             ContextRecord->Gpr0,
    00209             ContextRecord->Gpr1,
    00210             ContextRecord->Gpr2,
    00211             ContextRecord->Gpr3,
    00212             ContextRecord->Gpr4,
    00213             ContextRecord->Gpr5);
    00214
    00215     HalDisplayString(Buffer);
    00216
    00217     sprintf(Buffer,
    00218             " R6:%8lX  R7:%8lX  R8:%8lX  R9:%8lX R10:%8lX R11:%8lX\n",
    00219             ContextRecord->Gpr6,
    00220             ContextRecord->Gpr7,
    00221             ContextRecord->Gpr8,
    00222             ContextRecord->Gpr9,
    00223             ContextRecord->Gpr10,
    00224             ContextRecord->Gpr11);
    00225
    00226     HalDisplayString(Buffer);
    00227
    00228     sprintf(Buffer,
    00229             "R12:%8lX R13:%8lX R14:%8lX R15:%8lX R16:%8lX R17:%8lX\n",
    00230             ContextRecord->Gpr12,
    00231             ContextRecord->Gpr13,
    00232             ContextRecord->Gpr14,
    00233             ContextRecord->Gpr15,
    00234             ContextRecord->Gpr16,
    00235             ContextRecord->Gpr17);
    00236
    00237     HalDisplayString(Buffer);
    00238
    00239     sprintf(Buffer,
    00240             "R18:%8lX R19:%8lX R20:%8lX R21:%8lX R22:%8lX R23:%8lX\n",
    00241             ContextRecord->Gpr18,
    00242             ContextRecord->Gpr19,
    00243             ContextRecord->Gpr20,
    00244             ContextRecord->Gpr21,
    00245             ContextRecord->Gpr22,
    00246             ContextRecord->Gpr23);
    00247
    00248     HalDisplayString(Buffer);
    00249
    00250     sprintf(Buffer,
    00251             "R24:%8lX R25:%8lX R26:%8lX R27:%8lX R28:%8lX R29:%8lX\n",
    00252             ContextRecord->Gpr24,
    00253             ContextRecord->Gpr25,
    00254             ContextRecord->Gpr26,
    00255             ContextRecord->Gpr27,
    00256             ContextRecord->Gpr28,
    00257             ContextRecord->Gpr29);
    00258
    00259     HalDisplayString(Buffer);
    00260
    00261     sprintf(Buffer,
    00262             "R30:%8lX R31:%8lX  CR:%8lX CTR:%8lX XER:%8lX\n",
    00263             ContextRecord->Gpr30,
    00264             ContextRecord->Gpr31,
    00265             ContextRecord->Cr,
    00266             ContextRecord->Ctr,
    00267             ContextRecord->Xer);
    00268
    00269     HalDisplayString(Buffer);
    00270
    00271 #if 0
    00272
    00273     //
    00274     // I'd much rather see a longer stack trace and skip the floating
    00275     // point stuff when the system crashes.  plj
    00276     //
    00277
    00278     //
    00279     // Format and output the floating registers.
    00280     //
    00281     DumpFloat = (PULONG)(&ContextRecord->Fpr0);
    00282     sprintf(Buffer,
    00283             " F0- F3:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
    00284             *(DumpFloat+1),
    00285             *DumpFloat,
    00286             *(DumpFloat+3),
    00287             *(DumpFloat+2),
    00288             *(DumpFloat+5),
    00289             *(DumpFloat+4),
    00290             *(DumpFloat+7),
    00291             *(DumpFloat+6));
    00292
    00293     HalDisplayString(Buffer);
    00294
    00295     DumpFloat = (PULONG)(&ContextRecord->Fpr4);
    00296     sprintf(Buffer,
    00297             " F4- F7:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
    00298             *(DumpFloat+1),
    00299             *DumpFloat,
    00300             *(DumpFloat+3),
    00301             *(DumpFloat+2),
    00302             *(DumpFloat+5),
    00303             *(DumpFloat+4),
    00304             *(DumpFloat+7),
    00305             *(DumpFloat+6));
    00306
    00307     HalDisplayString(Buffer);
    00308
    00309     DumpFloat = (PULONG)(&ContextRecord->Fpr8);
    00310     sprintf(Buffer,
    00311             " F8-F11:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
    00312             *(DumpFloat+1),
    00313             *DumpFloat,
    00314             *(DumpFloat+3),
    00315             *(DumpFloat+2),
    00316             *(DumpFloat+5),
    00317             *(DumpFloat+4),
    00318             *(DumpFloat+7),
    00319             *(DumpFloat+6));
    00320
    00321     HalDisplayString(Buffer);
    00322
    00323     DumpFloat = (PULONG)(&ContextRecord->Fpr12);
    00324     sprintf(Buffer,
    00325             "F12-F15:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
    00326             *(DumpFloat+1),
    00327             *DumpFloat,
    00328             *(DumpFloat+3),
    00329             *(DumpFloat+2),
    00330             *(DumpFloat+5),
    00331             *(DumpFloat+4),
    00332             *(DumpFloat+7),
    00333             *(DumpFloat+6));
    00334
    00335     HalDisplayString(Buffer);
    00336
    00337     DumpFloat = (PULONG)(&ContextRecord->Fpr16);
    00338     sprintf(Buffer,
    00339             "F16-F19:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
    00340             *(DumpFloat+1),
    00341             *DumpFloat,
    00342             *(DumpFloat+3),
    00343             *(DumpFloat+2),
    00344             *(DumpFloat+5),
    00345             *(DumpFloat+4),
    00346             *(DumpFloat+7),
    00347             *(DumpFloat+6));
    00348
    00349     HalDisplayString(Buffer);
    00350
    00351     DumpFloat = (PULONG)(&ContextRecord->Fpr20);
    00352     sprintf(Buffer,
    00353             "F20-F23:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
    00354             *(DumpFloat+1),
    00355             *DumpFloat,
    00356             *(DumpFloat+3),
    00357             *(DumpFloat+2),
    00358             *(DumpFloat+5),
    00359             *(DumpFloat+4),
    00360             *(DumpFloat+7),
    00361             *(DumpFloat+6));
    00362
    00363     HalDisplayString(Buffer);
    00364
    00365     DumpFloat = (PULONG)(&ContextRecord->Fpr24);
    00366     sprintf(Buffer,
    00367             "F24-F27:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
    00368             *(DumpFloat+1),
    00369             *DumpFloat,
    00370             *(DumpFloat+3),
    00371             *(DumpFloat+2),
    00372             *(DumpFloat+5),
    00373             *(DumpFloat+4),
    00374             *(DumpFloat+7),
    00375             *(DumpFloat+6));
    00376
    00377     HalDisplayString(Buffer);
    00378
    00379     DumpFloat = (PULONG)(&ContextRecord->Fpr28);
    00380     sprintf(Buffer,
    00381             "F28-F31:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
    00382             *(DumpFloat+1),
    00383             *DumpFloat,
    00384             *(DumpFloat+3),
    00385             *(DumpFloat+2),
    00386             *(DumpFloat+5),
    00387             *(DumpFloat+4),
    00388             *(DumpFloat+7),
    00389             *(DumpFloat+6));
    00390
    00391     HalDisplayString(Buffer);
    00392
    00393
    00394     DumpFloat = (PULONG)(&ContextRecord->Fpscr);
    00395     sprintf(Buffer,
    00396             "  FPSCR:%08lX%08lX\n",
    00397             *(DumpFloat+1),
    00398             *DumpFloat);
    00399
    00400     HalDisplayString(Buffer);
    00401
    00402 #define STAKWALK 4
    00403 #else
    00404 #define STAKWALK 8
    00405 #endif
    00406
    00407     //
    00408     // Output short stack back trace with base address.
    00409     //
    00410
    00411     DllName.Length = 0;
    00412     DllName.Buffer = L"";
    00413     if (FunctionEntry != NULL) {
    00414         StackLimit = (ULONG)KeGetCurrentThread()->KernelStack;
    00415         HalDisplayString("Callee-Sp Return-Ra  Dll Base - Name\n");
    00416         for (Index = 0; Index < STAKWALK; Index += 1) {
    00417             ImageBase = KiPcToFileHeader((PVOID)ControlPc,
    00418                                          &ImageBase,
    00419                                          &DataTableEntry);
    00420
    00421             sprintf(Buffer,
    00422                     " %08lX %08lX : %08lX - %s\n",
    00423                     ContextRecord->Gpr1,
    00424                     NextPc + 4,
    00425                     ImageBase,
    00426                     (*UnicodeToAnsiRoutine)( (ImageBase != NULL) ? &DataTableEntry->BaseDllName : &DllName,
    00427                                              AnsiBuffer, sizeof( AnsiBuffer )));
    00428
    00429             HalDisplayString(Buffer);
    00430
    00431             if ((NextPc != ControlPc) || (ContextRecord->Gpr1 != LastStack)) {
    00432                 ControlPc = NextPc;
    00433                 LastStack = ContextRecord->Gpr1;
    00434                 FunctionEntry = KiLookupFunctionEntry(ControlPc);
    00435                 if ((FunctionEntry != NULL) && (LastStack < StackLimit)) {
    00436                     NextPc = RtlVirtualUnwind(ControlPc,
    00437                                               FunctionEntry,
    00438                                               ContextRecord,
    00439                                               &InFunction,
    00440                                               &EstablisherFrame,
    00441                                               NULL,
    00442                                               0,
    00443                                               0xffffffff);
    00444                 } else {
    00445                     NextPc = ContextRecord->Lr;
    00446                 }
    00447
    00448             } else {
    00449                 break;
    00450             }
    00451         }
    00452     }
    00453
    00454     //
    00455     // Output the build number and other useful information.
    00456     //
    00457
    00458     sprintf(Buffer,
    00459            "\nIRQL : %d, DPC Active : %s, SYSVER 0x%08x\n",
    00460            KeGetCurrentIrql(),
    00461            KeIsExecutingDpc() ? "TRUE" : "FALSE",
    00462            NtBuildNumber);
    00463
    00464     HalDisplayString(Buffer);
    00465
    00466     //
    00467     // Output the processor id and the primary cache sizes.
    00468     //
    00469
    00470     sprintf(Buffer,
    00471             "Processor Id: %d.%d, Icache: %d, Dcache: %d",
    00472             PCR->ProcessorVersion,
    00473             PCR->ProcessorRevision,
    00474             PCR->FirstLevelIcacheSize,
    00475             PCR->FirstLevelDcacheSize);
    00476
    00477     HalDisplayString(Buffer);
    00478
    00479     //
    00480     // If the display width is greater than 80 + 24 (the size of a DLL
    00481     // name and base address), then display all the modules loaded in
    00482     // the system.
    00483     //
    00484
    00485     HalQueryDisplayParameters(&DisplayWidth,
    00486                               &DisplayHeight,
    00487                               &DisplayColumn,
    00488                               &DisplayRow);
    00489
    00490     if (DisplayWidth > (80 + 24)) {
    00491         HalDisplayString("\n");
    00492         if (KeLoaderBlock != NULL) {
    00493             ModuleListHead = &KeLoaderBlock->LoadOrderListHead;
    00494
    00495         } else {
    00496             ModuleListHead = &PsLoadedModuleList;
    00497         }
    00498
    00499         //
    00500         // Output display headers.
    00501         //
    00502
    00503         Index = 1;
    00504         KiDisplayString(80, Index, "Dll Base DateStmp - Name");
    00505         NextEntry = ModuleListHead->Flink;
    00506         if (NextEntry != NULL) {
    00507
    00508             //
    00509             // Scan the list of loaded modules and display their base
    00510             // address and name.
    00511             //
    00512
    00513             while (NextEntry != ModuleListHead) {
    00514                 Index += 1;
    00515                 DataTableEntry = CONTAINING_RECORD(NextEntry,
    00516                                                    LDR_DATA_TABLE_ENTRY,
    00517                                                    InLoadOrderLinks);
    00518
    00519                 if (MmDbgReadCheck(DataTableEntry->DllBase) != NULL) {
    00520                     PIMAGE_NT_HEADERS NtHeaders;
    00521
    00522                     NtHeaders = RtlImageNtHeader(DataTableEntry->DllBase);
    00523                     DateStamp = NtHeaders->FileHeader.TimeDateStamp;
    00524
    00525                 } else {
    00526                     DateStamp = 0;
    00527                 }
    00528                 sprintf(Buffer,
    00529                         "%08lX %08lx - %s",
    00530                         DataTableEntry->DllBase,
    00531                         DateStamp,
    00532                         (*UnicodeToAnsiRoutine)( &DataTableEntry->BaseDllName, AnsiBuffer, sizeof( AnsiBuffer )));
    00533
    00534                 KiDisplayString(80, Index, Buffer);
    00535                 NextEntry = NextEntry->Flink;
    00536                 if (Index > DisplayHeight) {
    00537                     break;
    00538                 }
    00539             }
    00540         }
    00541     }
    00542
    00543     //
    00544     // Reset the current display position.
    00545     //
    00546
    00547     HalSetDisplayParameters(DisplayColumn, DisplayRow);
    00548
    00549     //
    00550     // The system has crashed, if we are running without the Kernel
    00551     // debugger attached, attach it now.
    00552     //
    00553
    00554     KdInitSystem(NULL, FALSE);
    00555
    00556     return;
    00557 }

VOID KiDisplayString | ( | IN ULONG | Column,
|  | IN ULONG | Row,
|  | IN PCHAR | Buffer
| ) |

| Referenced by KeDumpMachineState().

PRUNTIME_FUNCTION KiLookupFunctionEntry | ( | IN ULONG | ControlPc | ) |

| Referenced by KeDumpMachineState().

PVOID KiPcToFileHeader | ( | IN PVOID | PcValue,
|  | OUT PVOID * | BaseOfImage,
|  | OUT PLDR_DATA_TABLE_ENTRY * | DataTableEntry
| ) |

| Referenced by KeBugCheckEx(), KeDumpMachineState(), KiDumpParameterImages(), and KiLookupFunctionEntry().

## Variable Documentation

LIST_ENTRY PsLoadedModuleList

| Definition at line 64 of file ppc/dmpstate.c.