Leaked source code of windows server 2003
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.

250 lines
7.9 KiB

  1. /*-----------------------------------------------------------------------------
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module:
  4. exts.cpp
  5. Sampe file showing couple of extension examples
  6. -----------------------------------------------------------------------------*/
  7. #include "dbgexts.h"
  8. /*
  9. Sample extension to demonstrace ececuting debugger command
  10. */
  11. HRESULT CALLBACK
  12. cmdsample(PDEBUG_CLIENT Client, PCSTR args)
  13. {
  14. CHAR Input[256];
  15. INIT_API();
  16. //
  17. // Output a 10 frame stack
  18. //
  19. g_ExtControl->OutputStackTrace(DEBUG_OUTCTL_ALL_CLIENTS | // Flags on what to do with output
  20. DEBUG_OUTCTL_OVERRIDE_MASK |
  21. DEBUG_OUTCTL_NOT_LOGGED,
  22. NULL,
  23. 10, // number of frames to display
  24. DEBUG_STACK_FUNCTION_INFO | DEBUG_STACK_COLUMN_NAMES |
  25. DEBUG_STACK_ARGUMENTS | DEBUG_STACK_FRAME_ADDRESSES);
  26. //
  27. // Engine interface for print
  28. //
  29. g_ExtControl->Output(DEBUG_OUTCTL_ALL_CLIENTS, "\n\nDebugger module list\n");
  30. //
  31. // list all the modules by executing lm command
  32. //
  33. g_ExtControl->Execute(DEBUG_OUTCTL_ALL_CLIENTS |
  34. DEBUG_OUTCTL_OVERRIDE_MASK |
  35. DEBUG_OUTCTL_NOT_LOGGED,
  36. "lm", // Command to be executed
  37. DEBUG_EXECUTE_DEFAULT );
  38. //
  39. // Ask for user input
  40. //
  41. g_ExtControl->Output(DEBUG_OUTCTL_ALL_CLIENTS, "\n\n***User Input sample\n\nEnter Command to run : ");
  42. GetInputLine(NULL, &Input[0], sizeof(Input));
  43. g_ExtControl->Execute(DEBUG_OUTCTL_ALL_CLIENTS |
  44. DEBUG_OUTCTL_OVERRIDE_MASK |
  45. DEBUG_OUTCTL_NOT_LOGGED,
  46. Input, // Command to be executed
  47. DEBUG_EXECUTE_DEFAULT );
  48. EXIT_API();
  49. return S_OK;
  50. }
  51. /*
  52. Sample extension to read and dump a struct on target
  53. This reads the struct _EXCEPTION_RECORD which is defined as:
  54. typedef struct _EXCEPTION_RECORD {
  55. NTSTATUS ExceptionCode;
  56. ULONG ExceptionFlags;
  57. struct _EXCEPTION_RECORD *ExceptionRecord;
  58. PVOID ExceptionAddress;
  59. ULONG NumberParameters;
  60. ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
  61. } EXCEPTION_RECORD;
  62. */
  63. HRESULT CALLBACK
  64. structsample(PDEBUG_CLIENT Client, PCSTR args)
  65. {
  66. ULONG64 Address;
  67. INIT_API();
  68. Address = GetExpression(args);
  69. DWORD Buffer[4], cb;
  70. // Read and display first 4 dwords at Address
  71. if (ReadMemory(Address, &Buffer, sizeof(Buffer), &cb) && cb == sizeof(Buffer)) {
  72. dprintf("%p: %08lx %08lx %08lx %08lx\n\n", Address,
  73. Buffer[0], Buffer[1], Buffer[2], Buffer[3]);
  74. }
  75. //
  76. // Method 1 to dump a struct
  77. //
  78. dprintf("Method 1:\n");
  79. // Inititalze type read from the Address
  80. if (InitTypeRead(Address, _EXCEPTION_RECORD) != 0) {
  81. dprintf("Error in reading _EXCEPTION_RECORD at %p", // Use %p to print pointer values
  82. Address);
  83. } else {
  84. // read and dump the fields
  85. dprintf("_EXCEPTION_RECORD @ %p\n", Address);
  86. dprintf("\tExceptionCode : %lx\n", (ULONG) ReadField(ExceptionCode));
  87. dprintf("\tExceptionAddress : %p\n", ReadField(ExceptionAddress));
  88. dprintf("\tExceptionInformation[1] : %I64lx\n", ReadField(ExceptionInformation[1]));
  89. // And so on...
  90. }
  91. //
  92. // Method 2 to read a struct
  93. //
  94. ULONG64 ExceptionInformation_1, ExceptionAddress, ExceptionCode;
  95. dprintf("\n\nMethod 2:\n");
  96. // Read and dump the fields by specifying type and address individually
  97. if (GetFieldValue(Address, "_EXCEPTION_RECORD", "ExceptionCode", ExceptionCode)) {
  98. dprintf("Error in reading _EXCEPTION_RECORD at %p\n",
  99. Address);
  100. } else {
  101. // Pointers are read as ULONG64 values
  102. GetFieldValue(Address, "_EXCEPTION_RECORD", "ExceptionAddress", ExceptionAddress);
  103. GetFieldValue(Address, "_EXCEPTION_RECORD", "ExceptionInformation[1]", ExceptionInformation_1);
  104. // And so on..
  105. dprintf("_EXCEPTION_RECORD @ %p\n", Address);
  106. dprintf("\tExceptionCode : %lx\n", ExceptionCode);
  107. dprintf("\tExceptionAddress : %p\n", ExceptionAddress);
  108. dprintf("\tExceptionInformation[1] : %I64lx\n", ExceptionInformation_1);
  109. }
  110. ULONG64 Module;
  111. ULONG i, TypeId;
  112. CHAR Name[MAX_PATH];
  113. //
  114. // To get/list field names
  115. //
  116. g_ExtSymbols->GetSymbolTypeId("_EXCEPTION_RECORD", &TypeId, &Module);
  117. dprintf("Fields of _EXCEPTION_RECORD\n");
  118. for (i=0; ;i++) {
  119. HRESULT Hr;
  120. ULONG Offset=0;
  121. Hr = g_ExtSymbols2->GetFieldName(Module, TypeId, i, Name, MAX_PATH, NULL);
  122. if (Hr == S_OK) {
  123. g_ExtSymbols->GetFieldOffset(Module, TypeId, Name, &Offset);
  124. dprintf("%lx (+%03lx) %s\n", i, Offset, Name);
  125. } else if (Hr == E_INVALIDARG) {
  126. // All Fields done
  127. break;
  128. } else {
  129. dprintf("GetFieldName Failed %lx\n", Hr);
  130. break;
  131. }
  132. }
  133. //
  134. // Get name for an enumerate
  135. //
  136. // typedef enum {
  137. // Enum1,
  138. // Enum2,
  139. // Enum3,
  140. // } TEST_ENUM;
  141. //
  142. ULONG ValueOfEnum = 0;
  143. g_ExtSymbols->GetSymbolTypeId("TEST_ENUM", &TypeId, &Module);
  144. g_ExtSymbols2->GetConstantName(Module, TypeId, ValueOfEnum, Name, MAX_PATH, NULL);
  145. dprintf("Testenum %I64lx == %s\n", ExceptionCode, Name);
  146. // This prints out, Testenum 0 == Enum1
  147. //
  148. // Read an array
  149. //
  150. // typedef struct FOO_TYPE {
  151. // ULONG Bar;
  152. // ULONG Bar2;
  153. // } FOO_TYPE;
  154. //
  155. // FOO_TYPE sampleArray[20];
  156. ULONG Bar, Bar2;
  157. CHAR TypeName[100];
  158. for (i=0; i<20; i++) {
  159. sprintf(TypeName, "sampleArray[%lx]", i);
  160. if (GetFieldValue(0, TypeName, "Bar", Bar))
  161. break;
  162. GetFieldValue(0, TypeName, "Bar2", Bar2);
  163. dprintf("%16s - Bar %2ld Bar2 %ld\n", TypeName, Bar, Bar2);
  164. }
  165. EXIT_API();
  166. return S_OK;
  167. }
  168. /*
  169. This gets called (by DebugExtensionNotify whentarget is halted and is accessible
  170. */
  171. HRESULT
  172. NotifyOnTargetAccessible(PDEBUG_CONTROL Control)
  173. {
  174. dprintf("Extension dll detected a break");
  175. if (Connected) {
  176. dprintf(" connected to ");
  177. switch (TargetMachine) {
  178. case IMAGE_FILE_MACHINE_I386:
  179. dprintf("X86");
  180. break;
  181. case IMAGE_FILE_MACHINE_AMD64:
  182. dprintf("AMD64");
  183. break;
  184. case IMAGE_FILE_MACHINE_IA64:
  185. dprintf("IA64");
  186. break;
  187. default:
  188. dprintf("Other");
  189. break;
  190. }
  191. }
  192. dprintf("\n");
  193. //
  194. // show the top frame and execute dv to dump the locals here and return
  195. //
  196. Control->Execute(DEBUG_OUTCTL_ALL_CLIENTS |
  197. DEBUG_OUTCTL_OVERRIDE_MASK |
  198. DEBUG_OUTCTL_NOT_LOGGED,
  199. ".frame", // Command to be executed
  200. DEBUG_EXECUTE_DEFAULT );
  201. Control->Execute(DEBUG_OUTCTL_ALL_CLIENTS |
  202. DEBUG_OUTCTL_OVERRIDE_MASK |
  203. DEBUG_OUTCTL_NOT_LOGGED,
  204. "dv", // Command to be executed
  205. DEBUG_EXECUTE_DEFAULT );
  206. return S_OK;
  207. }
  208. /*
  209. A built-in help for the extension dll
  210. */
  211. HRESULT CALLBACK
  212. help(PDEBUG_CLIENT Client, PCSTR args)
  213. {
  214. INIT_API();
  215. dprintf("Help for dbgexts.dll\n"
  216. " cmdsample - This does stacktrace and lists\n"
  217. " help = Shows this help\n"
  218. " structsample <addr> - This dumps a struct at given address\n"
  219. );
  220. EXIT_API();
  221. return S_OK;
  222. }