334 lines
7.5 KiB
C
334 lines
7.5 KiB
C
/*++
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
|