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.

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


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 59 of file mips/dmpstate.c.

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

00069 : 00070 00071 This function formats and displays the machine state at the time of the 00072 to bug check. 00073 00074 Arguments: 00075 00076 ProcessorState - Supplies a pointer to a processor state record. 00077 00078 Buffer - Supplies a pointer to a buffer to be used to output machine 00079 state information. 00080 00081 BugCheckParameters - Supplies a pointer to an array of additional 00082 bug check information. 00083 00084 NumberOfParameters - Suppiles the size of the bug check parameters 00085 array. 00086 00087 UnicodeToAnsiRoutine - Supplies a pointer to a routine to convert Unicode strings 00088 to Ansi strings without touching paged translation tables. 00089 00090 Return Value: 00091 00092 None. 00093 00094 --*/ 00095 00096 { 00097 00098 PCONTEXT ContextRecord; 00099 ULONG ControlPc; 00100 PLDR_DATA_TABLE_ENTRY DataTableEntry; 00101 ULONG DisplayColumn; 00102 ULONG DisplayHeight; 00103 ULONG DisplayRow; 00104 ULONG DisplayWidth; 00105 UNICODE_STRING DllName; 00106 ULONG EstablisherFrame; 00107 PRUNTIME_FUNCTION FunctionEntry; 00108 PVOID ImageBase; 00109 ULONG Index; 00110 BOOLEAN InFunction; 00111 ULONG LastStack; 00112 PLIST_ENTRY ModuleListHead; 00113 PLIST_ENTRY NextEntry; 00114 ULONG NextPc; 00115 ULONG StackLimit; 00116 UCHAR AnsiBuffer[ 32 ]; 00117 ULONG DateStamp; 00118 00119 // 00120 // Query display parameters. 00121 // 00122 00123 HalQueryDisplayParameters(&DisplayWidth, 00124 &DisplayHeight, 00125 &DisplayColumn, 00126 &DisplayRow); 00127 00128 // 00129 // Display any addresses that fall within the range of any module in 00130 // the loaded module list. 00131 // 00132 00133 for (Index = 0; Index < NumberOfParameters; Index += 1) { 00134 ImageBase = KiPcToFileHeader((PVOID)*BugCheckParameters, 00135 &ImageBase, 00136 &DataTableEntry); 00137 00138 if (ImageBase != NULL) { 00139 sprintf(Buffer, 00140 "*** %08lX has base at %08lX - %s\n", 00141 *BugCheckParameters, 00142 ImageBase, 00143 (*UnicodeToAnsiRoutine)( &DataTableEntry->BaseDllName, AnsiBuffer, sizeof( AnsiBuffer ))); 00144 00145 HalDisplayString(Buffer); 00146 } 00147 00148 BugCheckParameters += 1; 00149 } 00150 00151 // 00152 // Virtually unwind to the caller of bug check. 00153 // 00154 00155 ContextRecord = &ProcessorState->ContextFrame; 00156 LastStack = (ULONG)ContextRecord->XIntSp; 00157 ControlPc = (ULONG)(ContextRecord->XIntRa - 4); 00158 NextPc = ControlPc; 00159 FunctionEntry = KiLookupFunctionEntry(ControlPc); 00160 if (FunctionEntry != NULL) { 00161 NextPc = RtlVirtualUnwind(ControlPc | 1, 00162 FunctionEntry, 00163 ContextRecord, 00164 &InFunction, 00165 &EstablisherFrame, 00166 NULL); 00167 } 00168 00169 // 00170 // At this point the context record contains the machine state at the 00171 // call to bug check. 00172 // 00173 // Put out the machine state at the time of the bugcheck. 00174 // 00175 00176 sprintf(Buffer, 00177 "\nMachine State at Call to Bug Check PC : %08lX PSR : %08lX\n\n", 00178 (ULONG)ContextRecord->XIntRa, 00179 ContextRecord->Psr); 00180 00181 HalDisplayString(Buffer); 00182 00183 // 00184 // Format and output the integer registers. 00185 // 00186 00187 sprintf(Buffer, 00188 "AT :%8lX V0 :%8lX V1 :%8lX A0 :%8lX\n", 00189 (ULONG)ContextRecord->XIntAt, 00190 (ULONG)ContextRecord->XIntV0, 00191 (ULONG)ContextRecord->XIntV1, 00192 (ULONG)ContextRecord->XIntA0); 00193 00194 HalDisplayString(Buffer); 00195 00196 sprintf(Buffer, 00197 "A1 :%8lX A2 :%8lX A3 :%8lX T0 :%8lX\n", 00198 (ULONG)ContextRecord->XIntA1, 00199 (ULONG)ContextRecord->XIntA2, 00200 (ULONG)ContextRecord->XIntA3, 00201 (ULONG)ContextRecord->XIntT0); 00202 00203 HalDisplayString(Buffer); 00204 00205 sprintf(Buffer, 00206 "T1 :%8lX T2 :%8lX T3 :%8lX T4 :%8lX\n", 00207 (ULONG)ContextRecord->XIntT1, 00208 (ULONG)ContextRecord->XIntT2, 00209 (ULONG)ContextRecord->XIntT3, 00210 (ULONG)ContextRecord->XIntT4); 00211 00212 HalDisplayString(Buffer); 00213 00214 sprintf(Buffer, 00215 "T5 :%8lX T6 :%8lX T7 :%8lX T8 :%8lX\n", 00216 (ULONG)ContextRecord->XIntT5, 00217 (ULONG)ContextRecord->XIntT6, 00218 (ULONG)ContextRecord->XIntT7, 00219 (ULONG)ContextRecord->XIntT8); 00220 00221 HalDisplayString(Buffer); 00222 00223 sprintf(Buffer, 00224 "T9 :%8lX S0 :%8lX S1 :%8lX S2 :%8lX\n", 00225 (ULONG)ContextRecord->XIntT9, 00226 (ULONG)ContextRecord->XIntS0, 00227 (ULONG)ContextRecord->XIntS1, 00228 (ULONG)ContextRecord->XIntS2); 00229 00230 HalDisplayString(Buffer); 00231 00232 sprintf(Buffer, 00233 "S3 :%8lX S4 :%8lX S5 :%8lX S6 :%8lX\n", 00234 (ULONG)ContextRecord->XIntS3, 00235 (ULONG)ContextRecord->XIntS4, 00236 (ULONG)ContextRecord->XIntS5, 00237 (ULONG)ContextRecord->XIntS6); 00238 00239 HalDisplayString(Buffer); 00240 00241 sprintf(Buffer, 00242 "S7 :%8lX S8 :%8lX GP :%8lX SP :%8lX\n", 00243 (ULONG)ContextRecord->XIntS7, 00244 (ULONG)ContextRecord->XIntS8, 00245 (ULONG)ContextRecord->XIntGp, 00246 (ULONG)ContextRecord->XIntSp); 00247 00248 HalDisplayString(Buffer); 00249 00250 sprintf(Buffer, 00251 "RA :%8lX LO :%8lX HI :%8lX FSR:%8lX\n", 00252 (ULONG)ContextRecord->XIntRa, 00253 (ULONG)ContextRecord->XIntLo, 00254 (ULONG)ContextRecord->XIntHi, 00255 (ULONG)ContextRecord->Fsr); 00256 00257 HalDisplayString(Buffer); 00258 00259 // 00260 // Format and output the firswt four floating registers. 00261 // 00262 00263 sprintf(Buffer, 00264 "F0 :%8lX F1 :%8lX F2 :%8lX F3 :%8lX\n", 00265 ContextRecord->FltF0, 00266 ContextRecord->FltF1, 00267 ContextRecord->FltF2, 00268 ContextRecord->FltF3); 00269 00270 HalDisplayString(Buffer); 00271 00272 sprintf(Buffer, 00273 "F4 :%8lX F5 :%8lX F6 :%8lX F7 :%8lX\n", 00274 ContextRecord->FltF4, 00275 ContextRecord->FltF5, 00276 ContextRecord->FltF6, 00277 ContextRecord->FltF7); 00278 00279 HalDisplayString(Buffer); 00280 00281 sprintf(Buffer, 00282 "F8 :%8lX F9 :%8lX F10:%8lX F11:%8lX\n", 00283 ContextRecord->FltF8, 00284 ContextRecord->FltF9, 00285 ContextRecord->FltF10, 00286 ContextRecord->FltF11); 00287 00288 HalDisplayString(Buffer); 00289 00290 sprintf(Buffer, 00291 "F12:%8lX F13:%8lX F14:%8lX F15:%8lX\n", 00292 ContextRecord->FltF12, 00293 ContextRecord->FltF13, 00294 ContextRecord->FltF14, 00295 ContextRecord->FltF15); 00296 00297 HalDisplayString(Buffer); 00298 00299 sprintf(Buffer, 00300 "F16:%8lX F17:%8lX F18:%8lX F19:%8lX\n", 00301 ContextRecord->FltF16, 00302 ContextRecord->FltF17, 00303 ContextRecord->FltF18, 00304 ContextRecord->FltF19); 00305 00306 HalDisplayString(Buffer); 00307 00308 sprintf(Buffer, 00309 "F20:%8lX F21:%8lX F22:%8lX F23:%8lX\n", 00310 ContextRecord->FltF20, 00311 ContextRecord->FltF21, 00312 ContextRecord->FltF22, 00313 ContextRecord->FltF23); 00314 00315 HalDisplayString(Buffer); 00316 00317 sprintf(Buffer, 00318 "F24:%8lX F25:%8lX F26:%8lX F27:%8lX\n", 00319 ContextRecord->FltF24, 00320 ContextRecord->FltF25, 00321 ContextRecord->FltF26, 00322 ContextRecord->FltF27); 00323 00324 HalDisplayString(Buffer); 00325 00326 sprintf(Buffer, 00327 "F28:%8lX F29:%8lX F30:%8lX F31:%8lX\n\n", 00328 ContextRecord->FltF28, 00329 ContextRecord->FltF29, 00330 ContextRecord->FltF30, 00331 ContextRecord->FltF31); 00332 00333 HalDisplayString(Buffer); 00334 00335 // 00336 // Output short stack back trace with base address. 00337 // 00338 00339 DllName.Length = 0; 00340 DllName.Buffer = L""; 00341 if (FunctionEntry != NULL) { 00342 StackLimit = (ULONG)KeGetCurrentThread()->KernelStack; 00343 HalDisplayString("Callee-Sp Return-Ra Dll Base - Name\n"); 00344 for (Index = 0; Index < 8; Index += 1) { 00345 ImageBase = KiPcToFileHeader((PVOID)ControlPc, 00346 &ImageBase, 00347 &DataTableEntry); 00348 00349 sprintf(Buffer, 00350 " %08lX %08lX : %08lX - %s\n", 00351 (ULONG)ContextRecord->XIntSp, 00352 NextPc + 4, 00353 ImageBase, 00354 (*UnicodeToAnsiRoutine)( (ImageBase != NULL) ? &DataTableEntry->BaseDllName : &DllName, 00355 AnsiBuffer, sizeof( AnsiBuffer ))); 00356 00357 HalDisplayString(Buffer); 00358 if ((NextPc != ControlPc) || ((ULONG)ContextRecord->XIntSp != LastStack)) { 00359 ControlPc = NextPc; 00360 LastStack = (ULONG)ContextRecord->XIntSp; 00361 FunctionEntry = KiLookupFunctionEntry(ControlPc); 00362 if ((FunctionEntry != NULL) && (LastStack < StackLimit)) { 00363 NextPc = RtlVirtualUnwind(ControlPc | 1, 00364 FunctionEntry, 00365 ContextRecord, 00366 &InFunction, 00367 &EstablisherFrame, 00368 NULL); 00369 } else { 00370 NextPc = (ULONG)ContextRecord->XIntRa; 00371 } 00372 00373 } else { 00374 break; 00375 } 00376 } 00377 } 00378 00379 // 00380 // Output the build number and other useful information. 00381 // 00382 00383 sprintf(Buffer, 00384 "\nIRQL : %d, DPC Active : %s, SYSVER 0x%08x\n", 00385 KeGetCurrentIrql(), 00386 KeIsExecutingDpc() ? "TRUE" : "FALSE", 00387 NtBuildNumber); 00388 00389 HalDisplayString(Buffer); 00390 00391 // 00392 // Output the processor id and the primary cache sizes. 00393 // 00394 00395 sprintf(Buffer, 00396 "Processor Id %d.%d, Icache : %d, Dcache : %d\n", 00397 (PCR->ProcessorId >> 8) & 0xff, 00398 PCR->ProcessorId & 0xff, 00399 PCR->FirstLevelIcacheSize, 00400 PCR->FirstLevelDcacheSize); 00401 00402 HalDisplayString(Buffer); 00403 00404 // 00405 // If the display width is greater than 80 + 24 (the size of a DLL 00406 // name and base address), then display all the modules loaded in 00407 // the system. 00408 // 00409 00410 HalQueryDisplayParameters(&DisplayWidth, 00411 &DisplayHeight, 00412 &DisplayColumn, 00413 &DisplayRow); 00414 00415 if (DisplayWidth > (80 + 24)) { 00416 if (KeLoaderBlock != NULL) { 00417 ModuleListHead = &KeLoaderBlock->LoadOrderListHead; 00418 00419 } else { 00420 ModuleListHead = &PsLoadedModuleList; 00421 } 00422 00423 // 00424 // Output display headers. 00425 // 00426 00427 Index = 1; 00428 KiDisplayString(80, Index, "Dll Base DateStmp - Name"); 00429 NextEntry = ModuleListHead->Flink; 00430 if (NextEntry != NULL) { 00431 00432 // 00433 // Scan the list of loaded modules and display their base 00434 // address and name. 00435 // 00436 00437 while (NextEntry != ModuleListHead) { 00438 Index += 1; 00439 DataTableEntry = CONTAINING_RECORD(NextEntry, 00440 LDR_DATA_TABLE_ENTRY, 00441 InLoadOrderLinks); 00442 00443 if (MmDbgReadCheck(DataTableEntry->DllBase) != NULL) { 00444 PIMAGE_NT_HEADERS NtHeaders; 00445 00446 NtHeaders = RtlImageNtHeader(DataTableEntry->DllBase); 00447 DateStamp = NtHeaders->FileHeader.TimeDateStamp; 00448 00449 } else { 00450 DateStamp = 0; 00451 } 00452 sprintf(Buffer, 00453 "%08lX %08lx - %s", 00454 DataTableEntry->DllBase, 00455 DateStamp, 00456 (*UnicodeToAnsiRoutine)( &DataTableEntry->BaseDllName, AnsiBuffer, sizeof( AnsiBuffer ))); 00457 00458 KiDisplayString(80, Index, Buffer); 00459 NextEntry = NextEntry->Flink; 00460 if (Index > DisplayHeight) { 00461 break; 00462 } 00463 } 00464 } 00465 } 00466 00467 // 00468 // Reset the current display position. 00469 // 00470 00471 HalSetDisplayParameters(DisplayColumn, DisplayRow); 00472 return; 00473 }

VOID KiDisplayString IN ULONG  Column,
IN ULONG  Row,
IN PCHAR  Buffer
 

Definition at line 476 of file mips/dmpstate.c.

References Buffer, HalDisplayString(), and HalSetDisplayParameters().

00484 : 00485 00486 This function display a string starting at the specified column and row 00487 position on the screen. 00488 00489 Arguments: 00490 00491 Column - Supplies the starting column of where the string is displayed. 00492 00493 Row - Supplies the starting row of where the string is displayed. 00494 00495 Bufer - Supplies a pointer to the string that is displayed. 00496 00497 Return Value: 00498 00499 None. 00500 00501 --*/ 00502 00503 { 00504 00505 // 00506 // Position the cursor and display the string. 00507 // 00508 00509 HalSetDisplayParameters(Column, Row); 00510 HalDisplayString(Buffer); 00511 return; 00512 }

PRUNTIME_FUNCTION KiLookupFunctionEntry IN ULONG  ControlPc  ) 
 

Definition at line 515 of file mips/dmpstate.c.

References KiPcToFileHeader(), NULL, RtlImageDirectoryEntryToData(), and TRUE.

00521 : 00522 00523 This function searches the currently active function tables for an entry 00524 that corresponds to the specified PC value. 00525 00526 Arguments: 00527 00528 ControlPc - Supplies the address of an instruction within the specified 00529 function. 00530 00531 Return Value: 00532 00533 If there is no entry in the function table for the specified PC, then 00534 NULL is returned. Otherwise, the address of the function table entry 00535 that corresponds to the specified PC is returned. 00536 00537 --*/ 00538 00539 { 00540 00541 PLDR_DATA_TABLE_ENTRY DataTableEntry; 00542 PRUNTIME_FUNCTION FunctionEntry; 00543 PRUNTIME_FUNCTION FunctionTable; 00544 ULONG SizeOfExceptionTable; 00545 LONG High; 00546 PVOID ImageBase; 00547 LONG Low; 00548 LONG Middle; 00549 00550 // 00551 // Search for the image that includes the specified PC value. 00552 // 00553 00554 ImageBase = KiPcToFileHeader((PVOID)ControlPc, 00555 &ImageBase, 00556 &DataTableEntry); 00557 00558 // 00559 // If an image is found that includes the specified PC, then locate the 00560 // function table for the image. 00561 // 00562 00563 if (ImageBase != NULL) { 00564 FunctionTable = (PRUNTIME_FUNCTION)RtlImageDirectoryEntryToData( 00565 ImageBase, TRUE, IMAGE_DIRECTORY_ENTRY_EXCEPTION, 00566 &SizeOfExceptionTable); 00567 00568 // 00569 // If a function table is located, then search the function table 00570 // for a function table entry for the specified PC. 00571 // 00572 00573 if (FunctionTable != NULL) { 00574 00575 // 00576 // Initialize search indicies. 00577 // 00578 00579 Low = 0; 00580 High = (SizeOfExceptionTable / sizeof(RUNTIME_FUNCTION)) - 1; 00581 00582 // 00583 // Perform binary search on the function table for a function table 00584 // entry that subsumes the specified PC. 00585 // 00586 00587 while (High >= Low) { 00588 00589 // 00590 // Compute next probe index and test entry. If the specified PC 00591 // is greater than of equal to the beginning address and less 00592 // than the ending address of the function table entry, then 00593 // return the address of the function table entry. Otherwise, 00594 // continue the search. 00595 // 00596 00597 Middle = (Low + High) >> 1; 00598 FunctionEntry = &FunctionTable[Middle]; 00599 if (ControlPc < FunctionEntry->BeginAddress) { 00600 High = Middle - 1; 00601 00602 } else if (ControlPc >= FunctionEntry->EndAddress) { 00603 Low = Middle + 1; 00604 00605 } else { 00606 00607 // 00608 // The capability exists for more than one function entry 00609 // to map to the same function. This permits a function to 00610 // have discontiguous code segments described by separate 00611 // function table entries. If the ending prologue address 00612 // is not within the limits of the begining and ending 00613 // address of the function able entry, then the prologue 00614 // ending address is the address of a function table entry 00615 // that accurately describes the ending prologue address. 00616 // 00617 00618 if ((FunctionEntry->PrologEndAddress < FunctionEntry->BeginAddress) || 00619 (FunctionEntry->PrologEndAddress >= FunctionEntry->EndAddress)) { 00620 FunctionEntry = (PRUNTIME_FUNCTION)FunctionEntry->PrologEndAddress; 00621 } 00622 00623 return FunctionEntry; 00624 } 00625 } 00626 } 00627 } 00628 00629 // 00630 // A function table entry for the specified PC was not found. 00631 // 00632 00633 return NULL; 00634 }

PVOID KiPcToFileHeader IN PVOID  PcValue,
OUT PVOID *  BaseOfImage,
OUT PLDR_DATA_TABLE_ENTRY *  DataTableEntry
 

Definition at line 637 of file mips/dmpstate.c.

References KeLoaderBlock, _LOADER_PARAMETER_BLOCK::LoadOrderListHead, NULL, and PsLoadedModuleList.

00645 : 00646 00647 This function returns the base of an image that contains the 00648 specified PcValue. An image contains the PcValue if the PcValue 00649 is within the ImageBase, and the ImageBase plus the size of the 00650 virtual image. 00651 00652 Arguments: 00653 00654 PcValue - Supplies a PcValue. 00655 00656 BaseOfImage - Returns the base address for the image containing the 00657 PcValue. This value must be added to any relative addresses in 00658 the headers to locate portions of the image. 00659 00660 DataTableEntry - Suppies a pointer to a variable that receives the 00661 address of the data table entry that describes the image. 00662 00663 Return Value: 00664 00665 NULL - No image was found that contains the PcValue. 00666 00667 NON-NULL - Returns the base address of the image that contain the 00668 PcValue. 00669 00670 --*/ 00671 00672 { 00673 00674 PLIST_ENTRY ModuleListHead; 00675 PLDR_DATA_TABLE_ENTRY Entry; 00676 PLIST_ENTRY Next; 00677 ULONG Bounds; 00678 PVOID ReturnBase, Base; 00679 00680 // 00681 // If the module list has been initialized, then scan the list to 00682 // locate the appropriate entry. 00683 // 00684 00685 if (KeLoaderBlock != NULL) { 00686 ModuleListHead = &KeLoaderBlock->LoadOrderListHead; 00687 00688 } else { 00689 ModuleListHead = &PsLoadedModuleList; 00690 } 00691 00692 ReturnBase = NULL; 00693 Next = ModuleListHead->Flink; 00694 if (Next != NULL) { 00695 while (Next != ModuleListHead) { 00696 Entry = CONTAINING_RECORD(Next, 00697 LDR_DATA_TABLE_ENTRY, 00698 InLoadOrderLinks); 00699 00700 Next = Next->Flink; 00701 Base = Entry->DllBase; 00702 Bounds = (ULONG)Base + Entry->SizeOfImage; 00703 if ((ULONG)PcValue >= (ULONG)Base && (ULONG)PcValue < Bounds) { 00704 *DataTableEntry = Entry; 00705 ReturnBase = Base; 00706 break; 00707 } 00708 } 00709 } 00710 00711 *BaseOfImage = ReturnBase; 00712 return ReturnBase; 00713 } }


Variable Documentation

LIST_ENTRY PsLoadedModuleList
 

Definition at line 56 of file mips/dmpstate.c.


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