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.


Generated on Sat May 15 19:43:28 2004 for test by doxygen 1.3.7