/*++ Copyright (c) 1992 Microsoft Corporation Module Name: faults.c Abstract: WinDbg Extension Api Author: Forrest Foltz (forrestf) Environment: User Mode. Revision History: --*/ #include "precomp.h" #pragma hdrstop #define DBGPRINT if(1) dprintf #define MAX_IMAGE_NAME_CHARS 15 typedef struct _ALIGNMENT_FAULT_IMAGE_DB *PALIGNMENT_FAULT_IMAGE_DB; typedef struct _ALIGNMENT_FAULT_LOCATION_DB *PALIGNMENT_FAULT_LOCATION_DB; typedef struct _ALIGNMENT_FAULT_IMAGE_DB { // // Head of singly-linked list of fault locations associated with this image // PALIGNMENT_FAULT_LOCATION_DB LocationHead; // // Total number of alignment faults associated with this image. // ULONG Count; // // Number of unique alignment fault locations found in this image // ULONG Instances; // // Name of the image // CHAR Name[ MAX_IMAGE_NAME_CHARS + 1 ]; } ALIGNMENT_FAULT_IMAGE_DB; typedef struct _ALIGNMENT_FAULT_LOCATION_DB { // // Pointer to fault image associated with this location // PALIGNMENT_FAULT_IMAGE_DB Image; // // Linkage for singly-linked list of fault locations associated with the // same image. // PALIGNMENT_FAULT_LOCATION_DB Next; // // Offset of the PC address within the image. // ULONG64 OffsetFromBase; // // Number of alignment faults taken at this location. // ULONG Count; } ALIGNMENT_FAULT_LOCATION_DB; BOOLEAN ReadAlignmentFaultData( OUT PALIGNMENT_FAULT_IMAGE_DB *ImageArray, OUT PALIGNMENT_FAULT_LOCATION_DB *LocationArray, OUT PULONG ImageArrayElements, OUT PULONG LocationArrayElements ); VOID PrintLocation( IN PALIGNMENT_FAULT_LOCATION_DB FaultLocation ); ULONG ReadUlong( ULONG64 Address ); int __cdecl sortByFrequency( const void *Elem1, const void *Elem2 ); DECLARE_API( alignmentfaults ) { PALIGNMENT_FAULT_IMAGE_DB imageArray; PALIGNMENT_FAULT_LOCATION_DB locationArray, location; ULONG imageArrayElements; ULONG locationArrayElements; ULONG i; BOOLEAN result; PALIGNMENT_FAULT_LOCATION_DB *sortLocationArray; // // Read the alignment fault data arrays // result = ReadAlignmentFaultData( &imageArray, &locationArray, &imageArrayElements, &locationArrayElements ); if (result == FALSE) { return E_INVALIDARG; } sortLocationArray = LocalAlloc(LPTR, sizeof(PVOID) * locationArrayElements); if ( !sortLocationArray ) { dprintf("Unable to allocate sortLocationArray\n"); return E_INVALIDARG; } for (i = 0; i < locationArrayElements; i++) { sortLocationArray[i] = &locationArray[i]; } qsort( sortLocationArray, locationArrayElements, sizeof(PALIGNMENT_FAULT_LOCATION_DB), sortByFrequency ); dprintf("%10s %s\n", "#faults","location"); for (i = 0; i < locationArrayElements; i++) { location = sortLocationArray[i]; PrintLocation(location); } LocalFree( sortLocationArray ); return S_OK; } int __cdecl sortByFrequency( const void *Elem1, const void *Elem2 ) { const ALIGNMENT_FAULT_LOCATION_DB *location1; const ALIGNMENT_FAULT_LOCATION_DB *location2; location1 = *((const ALIGNMENT_FAULT_LOCATION_DB **)Elem1); location2 = *((const ALIGNMENT_FAULT_LOCATION_DB **)Elem2); if (location1->Count < location2->Count) { return -1; } if (location1->Count > location2->Count) { return 1; } return 0; } VOID PrintLocation( IN PALIGNMENT_FAULT_LOCATION_DB FaultLocation ) { PALIGNMENT_FAULT_IMAGE_DB image; CHAR symbol[256]; ULONG64 displacement; image = FaultLocation->Image; dprintf("%10d %s+%x\n", FaultLocation->Count, image->Name, FaultLocation->OffsetFromBase); } BOOLEAN ReadAlignmentFaultData( OUT PALIGNMENT_FAULT_IMAGE_DB *ImageArray, OUT PALIGNMENT_FAULT_LOCATION_DB *LocationArray, OUT PULONG ImageArrayElements, OUT PULONG LocationArrayElements ) { ULONG imageCount; ULONG locationCount; ULONG i; ULONG index; ULONG allocSize; ULONG result; ULONG64 locationRecordArray, locationRecord; ULONG64 imageRecordArray, imageRecord; ULONG64 locationCountAddr; ULONG64 imageCountAddr; ULONG locationRecordSize; ULONG imageRecordSize; PALIGNMENT_FAULT_LOCATION_DB location, locationArray; PALIGNMENT_FAULT_IMAGE_DB image, imageArray; // // Get the count of images and locations // locationCountAddr = GetExpression ("KiAlignmentFaultLocationCount"); imageCountAddr = GetExpression ("KiAlignmentFaultImageCount"); locationCount = ReadUlong( locationCountAddr ); imageCount = ReadUlong( imageCountAddr ); if (locationCount == 0 || imageCount == 0) { dprintf("No alignment faults encountered\n"); return FALSE; } locationRecordArray = GetExpression ("KiAlignmentFaultLocations"); imageRecordArray = GetExpression ("KiAlignmentFaultImages"); if (locationRecordArray == 0 || imageRecordArray == 0) { return FALSE; } // // Get the sizes of the records as they exist on the target // machine // locationRecordSize = GetTypeSize("ALIGNMENT_FAULT_LOCATION"); imageRecordSize = GetTypeSize("ALIGNMENT_FAULT_IMAGE"); // // Allocate space for the location and image arrays // allocSize = sizeof(ALIGNMENT_FAULT_LOCATION_DB) * locationCount + sizeof(ALIGNMENT_FAULT_IMAGE_DB) * imageCount; locationArray = LocalAlloc(LPTR, allocSize); if (locationArray == NULL) { dprintf("Unable to allocate %d bytes of memory\n", allocSize); return FALSE; } imageArray = (PALIGNMENT_FAULT_IMAGE_DB)(locationArray + locationCount); // // Load the location records // location = locationArray; locationRecord = locationRecordArray; for (i = 0; i < locationCount; i++) { InitTypeRead(locationRecord, ALIGNMENT_FAULT_LOCATION); index = (ULONG)((ReadField(Image) - imageRecordArray) / imageRecordSize); location->Image = &imageArray[ index ]; index = (ULONG)((ReadField(Next) - locationRecordArray) / locationRecordSize); location->Next = &locationArray[ index ]; location->OffsetFromBase = ReadField(OffsetFromBase); location->Count = (ULONG)ReadField(Count); locationRecord += locationRecordSize; location += 1; } image = imageArray; imageRecord = imageRecordArray; for (i = 0; i < imageCount; i++) { InitTypeRead(imageRecord, ALIGNMENT_FAULT_IMAGE); index = (ULONG)((ReadField(LocationHead) - locationRecordArray) / locationRecordSize); image->LocationHead = &locationArray[ index ]; image->Count = (ULONG)ReadField(Count); image->Instances = (ULONG)ReadField(Instances); GetFieldOffset( "ALIGNMENT_FAULT_IMAGE", "Name", &index ); ReadMemory( imageRecord + index, &image->Name, sizeof(image->Name), &result ); imageRecord += imageRecordSize; image += 1; } *ImageArray = imageArray; *LocationArray = locationArray; *ImageArrayElements = imageCount; *LocationArrayElements = locationCount; return TRUE; }