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.

390 lines
9.1 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. trap.c
  5. Abstract:
  6. WinDbg Extension Api
  7. Revision History:
  8. --*/
  9. #include "precomp.h"
  10. #include "i386.h"
  11. #include "ia64.h"
  12. #pragma hdrstop
  13. extern ULONG64 STeip, STebp, STesp;
  14. extern ULONG64 ThreadLastDump;
  15. DECLARE_API( callback )
  16. /*++
  17. Routine Description:
  18. Arguments:
  19. args -
  20. Return Value:
  21. None
  22. --*/
  23. {
  24. ULONG64 Address;
  25. ULONG Flags;
  26. ULONG result;
  27. ULONG64 Thread;
  28. ULONG64 prevCallout ;
  29. INT calloutNum ;
  30. INT whichCallout ;
  31. ULONG64 InitialStack;
  32. ULONG64 TrFr;
  33. ULONG dwProcessor=0;
  34. GetCurrentProcessor(Client, &dwProcessor, NULL);
  35. Address = 0;
  36. whichCallout = 0 ;
  37. if (GetExpressionEx(args, &Address, &args)) {
  38. if (!sscanf(args, "%ld", &whichCallout)) {
  39. whichCallout = 0;
  40. }
  41. }
  42. if (Address == 0) {
  43. GetCurrentThreadAddr((USHORT)dwProcessor, &Address);
  44. }
  45. if (!DumpThreadEx(dwProcessor, "", Address, 0, Client))
  46. return E_INVALIDARG;
  47. GetFieldValue(Address, "ETHREAD", "Tcb.InitialStack", InitialStack);
  48. /*
  49. * now try and grab the contents of the stack
  50. */
  51. if (GetFieldValue(InitialStack, "KCALLOUT_FRAME", "TrFr", TrFr)) {
  52. dprintf("%08p: Unable to get callout frame\n", InitialStack);
  53. return E_INVALIDARG;
  54. }
  55. if (TargetMachine == IMAGE_FILE_MACHINE_I386) {
  56. /*
  57. * Save eip, esp, ebp for quick backtrace from this callback in case
  58. * they gave us a bogus callout frame.
  59. */
  60. GetFieldValue(InitialStack, "KCALLOUT_FRAME", "Ret", STeip);
  61. STesp = (ULONG) InitialStack ;
  62. GetFieldValue(InitialStack, "KCALLOUT_FRAME", "Ebp", STebp);
  63. }
  64. /*
  65. * Print the callout chain
  66. */
  67. calloutNum = 0 ;
  68. prevCallout = InitialStack ;
  69. if (TargetMachine == IMAGE_FILE_MACHINE_I386) {
  70. dprintf("Callout# ebp esp eip trapframe\n") ;
  71. } else {
  72. dprintf("Callout# esp trapframe\n") ;
  73. }
  74. while (prevCallout) {
  75. if (TargetMachine == IMAGE_FILE_MACHINE_I386) {
  76. ULONG Ret, Ebp;
  77. GetFieldValue(prevCallout, "KCALLOUT_FRAME", "Ebp", Ebp);
  78. GetFieldValue(prevCallout, "KCALLOUT_FRAME", "Ret", Ret);
  79. dprintf(" %3d %08lx %08p %08lx %08lx",
  80. calloutNum, Ebp, prevCallout,
  81. Ret, TrFr) ;
  82. if (calloutNum == whichCallout) {
  83. STeip = Ret ;
  84. STesp = (ULONG) prevCallout ;
  85. STebp = Ebp ;
  86. dprintf(" <-- !kb\n") ;
  87. }
  88. else
  89. dprintf("\n") ;
  90. } else {
  91. dprintf(" %3d %08p %08lx",
  92. calloutNum, prevCallout, TrFr) ;
  93. }
  94. /*
  95. * advance to the next callout and try to read it
  96. */
  97. calloutNum++ ;
  98. GetFieldValue(prevCallout, "KCALLOUT_FRAME", "CbStk", prevCallout);
  99. if (GetFieldValue(prevCallout, "KCALLOUT_FRAME", "TrFr", TrFr)) {
  100. dprintf("%08p: Unable to get callout frame\n", prevCallout);
  101. return E_INVALIDARG;
  102. }
  103. }
  104. dprintf("\n") ;
  105. if (calloutNum <= whichCallout) {
  106. dprintf("#(%ld) is out of range. Frame #0 selected.\n", calloutNum) ;
  107. }
  108. return S_OK;
  109. }
  110. DECLARE_API( kb )
  111. /*++
  112. --*/
  113. {
  114. dprintf("\n");
  115. dprintf(" \"!kb\" is no longer necessary as using \"kb\" after a \".cxr\" or \".trap\"\n");
  116. dprintf(" command will give you the stack for the faulting thread.\n");
  117. dprintf("\n");
  118. dprintf(" Type \"!cxr\" or \"!trap\" for more help on this.\n");
  119. dprintf("\n");
  120. return S_OK;
  121. }
  122. DECLARE_API( kv )
  123. /*++
  124. --*/
  125. {
  126. dprintf("\n");
  127. dprintf(" \"!kv\" is no longer necessary as using \"kv\" after a \".cxr\" or \".trap\"\n");
  128. dprintf(" command will give you the stack for the faulting thread.\n");
  129. dprintf("\n");
  130. dprintf(" Type \"!cxr\" or \"!trap\" for more help on this.\n");
  131. dprintf("\n");
  132. return S_OK;
  133. }
  134. #define HIGH(x) ((ULONG) ((x>>32) & 0xFFFFFFFF))
  135. #define LOW(x) ((ULONG) (x & 0xFFFFFFFF))
  136. VOID
  137. DisplayFullEmRegField(
  138. ULONG64 EmRegValue,
  139. EM_REG_FIELD EmRegFields[],
  140. ULONG Field
  141. )
  142. {
  143. dprintf( "\n %3.3s : %I64x : %-s",
  144. EmRegFields[Field].SubName,
  145. (EmRegValue >> EmRegFields[Field].Shift) & ((1 << EmRegFields[Field].Length) - 1),
  146. EmRegFields[Field].Name
  147. );
  148. return;
  149. } // DisplayFullEmRegField()
  150. VOID
  151. DisplayFullEmReg(
  152. IN ULONG64 Val,
  153. IN EM_REG_FIELD EmRegFields[],
  154. IN DISPLAY_MODE DisplayMode
  155. )
  156. {
  157. ULONG i, j;
  158. i = j = 0;
  159. if ( DisplayMode >= DISPLAY_MAX ) {
  160. while( j < EM_REG_BITS ) {
  161. DisplayFullEmRegField( Val, EmRegFields, i );
  162. j += EmRegFields[i].Length;
  163. i++;
  164. }
  165. }
  166. else {
  167. while( j < EM_REG_BITS ) {
  168. if ( !strstr(EmRegFields[i].Name, "reserved" ) &&
  169. !strstr(EmRegFields[i].Name, "ignored" ) ) {
  170. DisplayFullEmRegField( Val, EmRegFields, i );
  171. }
  172. j += EmRegFields[i].Length;
  173. i++;
  174. }
  175. }
  176. dprintf("\n");
  177. return;
  178. } // DisplayFullEmReg()
  179. #if 0
  180. //
  181. // ISR codes for General Exceptions: ISR{7:4}
  182. //
  183. #define ISR_ILLEGAL_OP 0 // Illegal operation fault
  184. #define ISR_PRIV_OP 1 // Privileged operation fault
  185. #define ISR_PRIV_REG 2 // Privileged register fault
  186. #define ISR_RESVD_REG 3 // Reserved register/field fault
  187. #define ISR_ILLEGAL_ISA 4 // Disabled instruction set transition fault
  188. #define ISR_ILLEGAL_HAZARD 8 // Illegal hazard fault
  189. //
  190. // ISR codes for Nat Consumption Faults: ISR{7:4}
  191. //
  192. #define ISR_NAT_REG 1 // Nat Register Consumption fault
  193. #define ISR_NAT_PAGE 2 // Nat Page Consumption fault
  194. //
  195. // For Traps ISR{4:0}
  196. //
  197. // FP trap
  198. #define ISR_FP_TRAP 0
  199. // Lower privilege transfer trap
  200. #define ISR_LP_TRAP 1
  201. // Taken branch trap
  202. #define ISR_TB_TRAP 2
  203. // Single step trap
  204. #define ISR_SS_TRAP 3
  205. // Unimplemented instruction address trap
  206. #define ISR_UI_TRAP 4
  207. ISR Settings for Non-Access Instructions
  208. Instruction ISR fields
  209. code{3:0} na r w
  210. tpa 0 1 0 0
  211. fc 1 1 1 0
  212. probe 2 1 0 or 1 a 0 or 1 a
  213. tak 3 1 0 0
  214. lfetch, lfetch.fault 4 1 1 0
  215. probe.fault 5 1 0 or 1 a 0 or 1 a
  216. a. Sets r or w or both to 1 depending on the probe form.
  217. #endif // 0
  218. EM_REG_FIELD EmIsrFields[] = {
  219. { "code", "interruption Code" , 0x10, 0 }, // 0-15
  220. { "vector", "IA32 exception vector number" , 0x8, 16 }, // 16-23
  221. { "rv", "reserved0", 0x8, 24 }, // 24-31
  222. { "x", "eXecute exception", 0x1, 32 }, // 32
  223. { "w", "Write exception", 0x1, 33 }, // 33
  224. { "r", "Read exception", 0x1, 34 }, // 34
  225. { "na", "Non-Access exception", 0x1, 35 }, // 35
  226. { "sp", "Speculative load exception", 0x1, 36 }, // 36
  227. { "rs", "Register Stack", 0x1, 37 }, // 37
  228. { "ir", "Invalid Register frame", 0x1, 38 }, // 38
  229. { "ni", "Nested Interruption", 0x1, 39 }, // 39
  230. { "so", "IA32 Supervisor Override", 0x1, 40 }, // 40
  231. { "ei", "Exception IA64 Instruction", 0x2, 41 }, // 41-42
  232. { "ed", "Exception Deferral", 0x1, 43 }, // 43
  233. { "rv", "reserved1", 0x14, 44 } // 44-63
  234. };
  235. VOID
  236. DisplayIsrIA64(
  237. IN const PCHAR Header,
  238. IN EM_ISR EmIsr,
  239. IN DISPLAY_MODE DisplayMode
  240. )
  241. {
  242. dprintf("%s", Header ? Header : "" );
  243. if ( DisplayMode >= DISPLAY_MED ) {
  244. DisplayFullEmReg( EM_ISRToULong64(EmIsr), EmIsrFields, DisplayMode );
  245. }
  246. else {
  247. dprintf(
  248. "ed ei so ni ir rs sp na r w x vector code\n\t\t "
  249. "%1I64x %1I64x %1I64x %1I64x %1I64x %1I64x %1I64x %1I64x %1I64x %1I64x %1I64x %I64x %I64x\n",
  250. EmIsr.ed,
  251. EmIsr.ei,
  252. EmIsr.so,
  253. EmIsr.ni,
  254. EmIsr.ir,
  255. EmIsr.rs,
  256. EmIsr.sp,
  257. EmIsr.na,
  258. EmIsr.r,
  259. EmIsr.w,
  260. EmIsr.x,
  261. EmIsr.vector,
  262. EmIsr.code
  263. );
  264. }
  265. return;
  266. } // DisplayIsrIA64()
  267. DECLARE_API( isr )
  268. /*++
  269. Routine Description:
  270. Arguments:
  271. args -
  272. Return Value:
  273. None
  274. --*/
  275. {
  276. ULONG64 isrValue;
  277. ULONG result;
  278. ULONG flags = 0;
  279. char *header;
  280. if (!GetExpressionEx(args,&isrValue, &args)) {
  281. dprintf("USAGE: !isr 0xValue [display_mode:0,1,2]\n");
  282. dprintf("USAGE: !isr @isr [display_mode:0,1,2]\n");
  283. return E_INVALIDARG;
  284. } else {
  285. flags = (ULONG) GetExpression(args);
  286. }
  287. header = (flags > DISPLAY_MIN) ? NULL : "\tisr:\t";
  288. if (TargetMachine != IMAGE_FILE_MACHINE_IA64)
  289. {
  290. dprintf("!isr not implemented for this architecture.\n");
  291. }
  292. else
  293. {
  294. DisplayIsrIA64( header, ULong64ToEM_ISR(isrValue), (DISPLAY_MODE) flags );
  295. }
  296. return S_OK;
  297. } // !isr