Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

333 lines
7.5 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. faults.c
  5. Abstract:
  6. WinDbg Extension Api
  7. Author:
  8. Forrest Foltz (forrestf)
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. #define DBGPRINT if(1) dprintf
  16. #define MAX_IMAGE_NAME_CHARS 15
  17. typedef struct _ALIGNMENT_FAULT_IMAGE_DB *PALIGNMENT_FAULT_IMAGE_DB;
  18. typedef struct _ALIGNMENT_FAULT_LOCATION_DB *PALIGNMENT_FAULT_LOCATION_DB;
  19. typedef struct _ALIGNMENT_FAULT_IMAGE_DB {
  20. //
  21. // Head of singly-linked list of fault locations associated with this image
  22. //
  23. PALIGNMENT_FAULT_LOCATION_DB LocationHead;
  24. //
  25. // Total number of alignment faults associated with this image.
  26. //
  27. ULONG Count;
  28. //
  29. // Number of unique alignment fault locations found in this image
  30. //
  31. ULONG Instances;
  32. //
  33. // Name of the image
  34. //
  35. CHAR Name[ MAX_IMAGE_NAME_CHARS + 1 ];
  36. } ALIGNMENT_FAULT_IMAGE_DB;
  37. typedef struct _ALIGNMENT_FAULT_LOCATION_DB {
  38. //
  39. // Pointer to fault image associated with this location
  40. //
  41. PALIGNMENT_FAULT_IMAGE_DB Image;
  42. //
  43. // Linkage for singly-linked list of fault locations associated with the
  44. // same image.
  45. //
  46. PALIGNMENT_FAULT_LOCATION_DB Next;
  47. //
  48. // Offset of the PC address within the image.
  49. //
  50. ULONG64 OffsetFromBase;
  51. //
  52. // Number of alignment faults taken at this location.
  53. //
  54. ULONG Count;
  55. } ALIGNMENT_FAULT_LOCATION_DB;
  56. BOOLEAN
  57. ReadAlignmentFaultData(
  58. OUT PALIGNMENT_FAULT_IMAGE_DB *ImageArray,
  59. OUT PALIGNMENT_FAULT_LOCATION_DB *LocationArray,
  60. OUT PULONG ImageArrayElements,
  61. OUT PULONG LocationArrayElements
  62. );
  63. VOID
  64. PrintLocation(
  65. IN PALIGNMENT_FAULT_LOCATION_DB FaultLocation
  66. );
  67. ULONG
  68. ReadUlong(
  69. ULONG64 Address
  70. );
  71. int
  72. __cdecl
  73. sortByFrequency(
  74. const void *Elem1,
  75. const void *Elem2
  76. );
  77. DECLARE_API( alignmentfaults )
  78. {
  79. PALIGNMENT_FAULT_IMAGE_DB imageArray;
  80. PALIGNMENT_FAULT_LOCATION_DB locationArray, location;
  81. ULONG imageArrayElements;
  82. ULONG locationArrayElements;
  83. ULONG i;
  84. BOOLEAN result;
  85. PALIGNMENT_FAULT_LOCATION_DB *sortLocationArray;
  86. //
  87. // Read the alignment fault data arrays
  88. //
  89. result = ReadAlignmentFaultData( &imageArray,
  90. &locationArray,
  91. &imageArrayElements,
  92. &locationArrayElements );
  93. if (result == FALSE) {
  94. return E_INVALIDARG;
  95. }
  96. sortLocationArray = LocalAlloc(LPTR, sizeof(PVOID) *
  97. locationArrayElements);
  98. if ( !sortLocationArray ) {
  99. dprintf("Unable to allocate sortLocationArray\n");
  100. return E_INVALIDARG;
  101. }
  102. for (i = 0; i < locationArrayElements; i++) {
  103. sortLocationArray[i] = &locationArray[i];
  104. }
  105. qsort( sortLocationArray,
  106. locationArrayElements,
  107. sizeof(PALIGNMENT_FAULT_LOCATION_DB),
  108. sortByFrequency );
  109. dprintf("%10s %s\n", "#faults","location");
  110. for (i = 0; i < locationArrayElements; i++) {
  111. location = sortLocationArray[i];
  112. PrintLocation(location);
  113. }
  114. LocalFree( sortLocationArray );
  115. return S_OK;
  116. }
  117. int
  118. __cdecl
  119. sortByFrequency(
  120. const void *Elem1,
  121. const void *Elem2
  122. )
  123. {
  124. const ALIGNMENT_FAULT_LOCATION_DB *location1;
  125. const ALIGNMENT_FAULT_LOCATION_DB *location2;
  126. location1 = *((const ALIGNMENT_FAULT_LOCATION_DB **)Elem1);
  127. location2 = *((const ALIGNMENT_FAULT_LOCATION_DB **)Elem2);
  128. if (location1->Count < location2->Count) {
  129. return -1;
  130. }
  131. if (location1->Count > location2->Count) {
  132. return 1;
  133. }
  134. return 0;
  135. }
  136. VOID
  137. PrintLocation(
  138. IN PALIGNMENT_FAULT_LOCATION_DB FaultLocation
  139. )
  140. {
  141. PALIGNMENT_FAULT_IMAGE_DB image;
  142. CHAR symbol[256];
  143. ULONG64 displacement;
  144. image = FaultLocation->Image;
  145. dprintf("%10d %s+%x\n",
  146. FaultLocation->Count,
  147. image->Name,
  148. FaultLocation->OffsetFromBase);
  149. }
  150. BOOLEAN
  151. ReadAlignmentFaultData(
  152. OUT PALIGNMENT_FAULT_IMAGE_DB *ImageArray,
  153. OUT PALIGNMENT_FAULT_LOCATION_DB *LocationArray,
  154. OUT PULONG ImageArrayElements,
  155. OUT PULONG LocationArrayElements
  156. )
  157. {
  158. ULONG imageCount;
  159. ULONG locationCount;
  160. ULONG i;
  161. ULONG index;
  162. ULONG allocSize;
  163. ULONG result;
  164. ULONG64 locationRecordArray, locationRecord;
  165. ULONG64 imageRecordArray, imageRecord;
  166. ULONG64 locationCountAddr;
  167. ULONG64 imageCountAddr;
  168. ULONG locationRecordSize;
  169. ULONG imageRecordSize;
  170. PALIGNMENT_FAULT_LOCATION_DB location, locationArray;
  171. PALIGNMENT_FAULT_IMAGE_DB image, imageArray;
  172. //
  173. // Get the count of images and locations
  174. //
  175. locationCountAddr = GetExpression ("KiAlignmentFaultLocationCount");
  176. imageCountAddr = GetExpression ("KiAlignmentFaultImageCount");
  177. locationCount = ReadUlong( locationCountAddr );
  178. imageCount = ReadUlong( imageCountAddr );
  179. if (locationCount == 0 || imageCount == 0) {
  180. dprintf("No alignment faults encountered\n");
  181. return FALSE;
  182. }
  183. locationRecordArray = GetExpression ("KiAlignmentFaultLocations");
  184. imageRecordArray = GetExpression ("KiAlignmentFaultImages");
  185. if (locationRecordArray == 0 || imageRecordArray == 0) {
  186. return FALSE;
  187. }
  188. //
  189. // Get the sizes of the records as they exist on the target
  190. // machine
  191. //
  192. locationRecordSize = GetTypeSize("ALIGNMENT_FAULT_LOCATION");
  193. imageRecordSize = GetTypeSize("ALIGNMENT_FAULT_IMAGE");
  194. //
  195. // Allocate space for the location and image arrays
  196. //
  197. allocSize = sizeof(ALIGNMENT_FAULT_LOCATION_DB) * locationCount +
  198. sizeof(ALIGNMENT_FAULT_IMAGE_DB) * imageCount;
  199. locationArray = LocalAlloc(LPTR, allocSize);
  200. if (locationArray == NULL) {
  201. dprintf("Unable to allocate %d bytes of memory\n", allocSize);
  202. return FALSE;
  203. }
  204. imageArray = (PALIGNMENT_FAULT_IMAGE_DB)(locationArray + locationCount);
  205. //
  206. // Load the location records
  207. //
  208. location = locationArray;
  209. locationRecord = locationRecordArray;
  210. for (i = 0; i < locationCount; i++) {
  211. InitTypeRead(locationRecord, ALIGNMENT_FAULT_LOCATION);
  212. index = (ULONG)((ReadField(Image) - imageRecordArray) / imageRecordSize);
  213. location->Image = &imageArray[ index ];
  214. index = (ULONG)((ReadField(Next) - locationRecordArray) / locationRecordSize);
  215. location->Next = &locationArray[ index ];
  216. location->OffsetFromBase = ReadField(OffsetFromBase);
  217. location->Count = (ULONG)ReadField(Count);
  218. locationRecord += locationRecordSize;
  219. location += 1;
  220. }
  221. image = imageArray;
  222. imageRecord = imageRecordArray;
  223. for (i = 0; i < imageCount; i++) {
  224. InitTypeRead(imageRecord, ALIGNMENT_FAULT_IMAGE);
  225. index = (ULONG)((ReadField(LocationHead) - locationRecordArray) / locationRecordSize);
  226. image->LocationHead = &locationArray[ index ];
  227. image->Count = (ULONG)ReadField(Count);
  228. image->Instances = (ULONG)ReadField(Instances);
  229. GetFieldOffset( "ALIGNMENT_FAULT_IMAGE", "Name", &index );
  230. ReadMemory( imageRecord + index,
  231. &image->Name,
  232. sizeof(image->Name),
  233. &result );
  234. imageRecord += imageRecordSize;
  235. image += 1;
  236. }
  237. *ImageArray = imageArray;
  238. *LocationArray = locationArray;
  239. *ImageArrayElements = imageCount;
  240. *LocationArrayElements = locationCount;
  241. return TRUE;
  242. }