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.

480 lines
11 KiB

  1. #include <windows.h>
  2. #include <wtypes.h>
  3. #include <wdbgexts.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <ntverp.h>
  8. #include "tracelog.h"
  9. #include "event.h"
  10. void PrintTraceLogEntry(FILE *outfile, PTRACEENTRY TraceEntry);
  11. void PrintTraceLogEntry(FILE *outfile, PTRACEENTRY TraceEntry);
  12. EXT_API_VERSION ApiVersion = { 4, 0, EXT_API_VERSION_NUMBER, 0 };
  13. WINDBG_EXTENSION_APIS ExtensionApis;
  14. USHORT SavedMajorVersion;
  15. USHORT SavedMinorVersion;
  16. // ======================================================================
  17. #define MAXREAD 3500
  18. BOOL ReadMemoryEx(ULONG_PTR From, ULONG_PTR To, ULONG Size, PULONG OutBytesRead)
  19. {
  20. ULONG BytesRead;
  21. ULONG TotalBytesRead = 0;
  22. BOOL success;
  23. // dprintf("ReadMemoryEx: reading %08x bytes from %08x to %08x\n", Size, From, To);
  24. while (Size)
  25. {
  26. if (CheckControlC())
  27. return 0;
  28. if (Size > MAXREAD)
  29. {
  30. // dprintf("(reading %08x bytes from %08x to %08x)\n", MAXREAD, From, To);
  31. success = ReadMemory((ULONG_PTR)From, (PVOID)To, MAXREAD, &BytesRead);
  32. if (!success)
  33. {
  34. dprintf("Problem reading memory at %x for %x bytes\n", From, MAXREAD);
  35. break;
  36. }
  37. TotalBytesRead += BytesRead;
  38. }
  39. else
  40. {
  41. // dprintf("(reading %08x bytes from %08x to %08x)\n", Size, From, To);
  42. success = ReadMemory((ULONG_PTR)From, (PVOID)To, Size, &BytesRead);
  43. if (!success)
  44. {
  45. dprintf("Problem reading memory at %x for %x bytes\n", From, Size);
  46. break;
  47. }
  48. TotalBytesRead += BytesRead;
  49. }
  50. if (Size > MAXREAD)
  51. {
  52. Size -= MAXREAD;
  53. From += MAXREAD;
  54. To += MAXREAD;
  55. }
  56. else
  57. Size = 0;
  58. }
  59. *OutBytesRead = TotalBytesRead;
  60. return success;
  61. }
  62. // ======================================================================
  63. ULONG_PTR GetTraceLogAddress(VOID)
  64. {
  65. ULONG_PTR TargetTraceLog;
  66. PUCHAR symbol = "ATMLANE!TraceLog";
  67. TargetTraceLog = (ULONG_PTR)GetExpression(symbol);
  68. if ( !TargetTraceLog )
  69. {
  70. dprintf("Unable to resolve symbol \"%s\". Try .reload cmd.\n", symbol);
  71. return 0;
  72. }
  73. return TargetTraceLog;
  74. }
  75. // ======================================================================
  76. DllInit(
  77. HANDLE hModule,
  78. DWORD dwReason,
  79. DWORD dwReserved
  80. )
  81. {
  82. switch (dwReason) {
  83. case DLL_THREAD_ATTACH:
  84. break;
  85. case DLL_THREAD_DETACH:
  86. break;
  87. case DLL_PROCESS_DETACH:
  88. break;
  89. case DLL_PROCESS_ATTACH:
  90. break;
  91. }
  92. return TRUE;
  93. }
  94. // ======================================================================
  95. VOID
  96. WinDbgExtensionDllInit(
  97. PWINDBG_EXTENSION_APIS lpExtensionApis,
  98. USHORT MajorVersion,
  99. USHORT MinorVersion
  100. )
  101. {
  102. ExtensionApis = *lpExtensionApis;
  103. SavedMajorVersion = MajorVersion;
  104. SavedMinorVersion = MinorVersion;
  105. return;
  106. }
  107. // ======================================================================
  108. DECLARE_API( version )
  109. {
  110. #if DBG
  111. PCHAR DebuggerType = "Checked";
  112. #else
  113. PCHAR DebuggerType = "Free";
  114. #endif
  115. dprintf("%s Extension dll for Build %d debugging %s kernel for Build %d\n",
  116. DebuggerType,
  117. VER_PRODUCTBUILD,
  118. SavedMajorVersion == 0x0c ? "Checked" : "Free",
  119. SavedMinorVersion
  120. );
  121. }
  122. // ======================================================================
  123. VOID
  124. CheckVersion(
  125. VOID
  126. )
  127. {
  128. #if DBG
  129. if ((SavedMajorVersion != 0x0c) || (SavedMinorVersion != VER_PRODUCTBUILD)) {
  130. dprintf("\r\n*** Extension DLL(%d Checked) does not match target system(%d %s)\r\n\r\n",
  131. VER_PRODUCTBUILD, SavedMinorVersion, (SavedMajorVersion==0x0f) ? "Free" : "Checked" );
  132. }
  133. #else
  134. if ((SavedMajorVersion != 0x0f) || (SavedMinorVersion != VER_PRODUCTBUILD)) {
  135. dprintf("\r\n*** Extension DLL(%d Free) does not match target system(%d %s)\r\n\r\n",
  136. VER_PRODUCTBUILD, SavedMinorVersion, (SavedMajorVersion==0x0f) ? "Free" : "Checked" );
  137. }
  138. #endif
  139. }
  140. // ======================================================================
  141. LPEXT_API_VERSION
  142. ExtensionApiVersion(
  143. VOID
  144. )
  145. {
  146. return &ApiVersion;
  147. }
  148. // ======================================================================
  149. DECLARE_API(dumplog)
  150. {
  151. ULONG_PTR TargetTraceLogAddress;
  152. TRACELOG TargetTraceLog;
  153. TRACELOG LocalTraceLog;
  154. PUCHAR LocalLogStorage;
  155. PTRACEENTRY TraceEntry;
  156. PUCHAR CurString, NullPos;
  157. UCHAR SaveChar;
  158. ULONG LogLength;
  159. ULONG bytesread, firstsize;
  160. char * indexstr, *filenamestr;
  161. ULONG index;
  162. FILE * outfile;
  163. filenamestr = strtok((char *)args, " ");
  164. if (filenamestr == NULL)
  165. {
  166. dprintf("usage: dumplog <filename>\n");
  167. return;
  168. }
  169. TargetTraceLogAddress = GetTraceLogAddress();
  170. if (!TargetTraceLogAddress)
  171. return;
  172. // read trace log struct out of target's memory
  173. if (!ReadMemoryEx( (ULONG_PTR)TargetTraceLogAddress, (ULONG_PTR)&TargetTraceLog,
  174. sizeof(TRACELOG), &bytesread))
  175. return;
  176. #if 1
  177. // display trace log vars
  178. dprintf("TraceLog\n");
  179. dprintf("\tStorage = 0x%08x\n", TargetTraceLog.Storage);
  180. dprintf("\tSize = 0x%08x\n", TargetTraceLog.StorageSizeBytes);
  181. dprintf("\tFirst = 0x%08x\n", TargetTraceLog.First);
  182. dprintf("\tLast = 0x%08x\n", TargetTraceLog.Last);
  183. dprintf("\tCurrent = 0x%08x\n", TargetTraceLog.Current);
  184. #endif
  185. // see if logging enabled (i.e. log has storage allocated
  186. if (TargetTraceLog.Storage == NULL)
  187. {
  188. dprintf("Trace Log is disabled\n");
  189. return;
  190. }
  191. // alloc local memory for log
  192. LocalLogStorage = (PUCHAR) malloc(TargetTraceLog.StorageSizeBytes);
  193. if (LocalLogStorage == NULL)
  194. {
  195. dprintf("can't alloc %d bytes for local storage\n",
  196. TargetTraceLog.StorageSizeBytes);
  197. return;
  198. }
  199. // open the output file
  200. outfile = fopen(filenamestr, "wt");
  201. if (outfile == NULL)
  202. {
  203. dprintf("open of file '%s' failed, errno = %d\n", filenamestr, errno);
  204. free(LocalLogStorage);
  205. return;
  206. }
  207. // read the log out of target's memory
  208. dprintf("reading log from target system, please wait...\n");
  209. if (!ReadMemoryEx((ULONG_PTR)TargetTraceLog.Storage, (ULONG_PTR)LocalLogStorage,
  210. TargetTraceLog.StorageSizeBytes, &bytesread))
  211. {
  212. fclose(outfile);
  213. free(LocalLogStorage);
  214. return;
  215. }
  216. // convert addresses to local trace log
  217. LocalTraceLog.Storage = LocalLogStorage;
  218. LocalTraceLog.First = (PTRACEENTRY) LocalTraceLog.Storage;
  219. LocalTraceLog.Last = LocalTraceLog.First +
  220. (TargetTraceLog.Last - TargetTraceLog.First);
  221. LocalTraceLog.Current = LocalTraceLog.First +
  222. (TargetTraceLog.Current - TargetTraceLog.First);
  223. // loop thru the trace log printing out the values
  224. TraceEntry = LocalTraceLog.Current - 1;
  225. dprintf("writing formatted log to file...\n");
  226. for (;;)
  227. {
  228. if (TraceEntry < LocalTraceLog.First)
  229. TraceEntry = LocalTraceLog.Last;
  230. if (TraceEntry->EventId == 0 || TraceEntry == LocalTraceLog.Current)
  231. {
  232. dprintf("done.\n");
  233. break;
  234. }
  235. PrintTraceLogEntry(outfile, TraceEntry);
  236. TraceEntry--;
  237. if (CheckControlC())
  238. {
  239. dprintf("Aborted before end of log.\n");
  240. break;
  241. }
  242. }
  243. // cleanup
  244. fclose(outfile);
  245. free(LocalLogStorage);
  246. }
  247. // ======================================================================
  248. DECLARE_API( help )
  249. {
  250. dprintf("ATMLANE driver kd extensions\n\n");
  251. dprintf("\tdumplog <filename> - dumps & formats tracelog buffer to file\n");
  252. }
  253. // ======================================================================
  254. void PrintTraceLogEntry(FILE *outfile, PTRACEENTRY TraceEntry)
  255. {
  256. ULONG params, i;
  257. switch (TraceEntry->EventId)
  258. {
  259. case TL_MSENDPKTIN:
  260. fprintf(outfile, "[% 10u] MSENDPKTIN: PktCnt %d\n",
  261. TraceEntry->Time,
  262. TraceEntry->Params[0]
  263. );
  264. break;
  265. case TL_MSENDPKTBEGIN:
  266. fprintf(outfile, "[% 10u] MSENDPKTBEGIN: Index %d Pkt %x\n",
  267. TraceEntry->Time,
  268. TraceEntry->Params[0],
  269. TraceEntry->Params[1]
  270. );
  271. break;
  272. case TL_MSENDPKTEND:
  273. fprintf(outfile, "[% 10u] MSENDPKTEND: Index %d Pkt %x Status %x\n",
  274. TraceEntry->Time,
  275. TraceEntry->Params[0],
  276. TraceEntry->Params[1],
  277. TraceEntry->Params[2]
  278. );
  279. break;
  280. case TL_MSENDPKTOUT:
  281. fprintf(outfile, "[% 10u] MSENDPKTOUT\n",
  282. TraceEntry->Time,
  283. TraceEntry->Params[0]
  284. );
  285. break;
  286. case TL_MSENDCOMPL:
  287. fprintf(outfile, "[% 10u] MSENDCOMPL: Pkt %x Status %x\n",
  288. TraceEntry->Time,
  289. TraceEntry->Params[0],
  290. TraceEntry->Params[1]
  291. );
  292. break;
  293. case TL_WRAPSEND:
  294. fprintf(outfile, "[% 10u] WRAPSEND: From %x To %x Bcnt %d Len %d\n",
  295. TraceEntry->Time,
  296. TraceEntry->Params[0],
  297. TraceEntry->Params[1],
  298. TraceEntry->Params[2],
  299. TraceEntry->Params[3]
  300. );
  301. break;
  302. case TL_UNWRAPSEND:
  303. fprintf(outfile, "[% 10u] UNWRAPSEND: From %x To %x Bcnt %d Len %d\n",
  304. TraceEntry->Time,
  305. TraceEntry->Params[0],
  306. TraceEntry->Params[1],
  307. TraceEntry->Params[2],
  308. TraceEntry->Params[3]
  309. );
  310. break;
  311. case TL_WRAPRECV:
  312. fprintf(outfile, "[% 10u] WRAPRECV: From %x To %x Bcnt %d Len %d\n",
  313. TraceEntry->Time,
  314. TraceEntry->Params[0],
  315. TraceEntry->Params[1],
  316. TraceEntry->Params[2],
  317. TraceEntry->Params[3]
  318. );
  319. break;
  320. case TL_UNWRAPRECV:
  321. fprintf(outfile, "[% 10u] UNWRAPRECV: From %x To %x Bcnt %d Len %d\n",
  322. TraceEntry->Time,
  323. TraceEntry->Params[0],
  324. TraceEntry->Params[1],
  325. TraceEntry->Params[2],
  326. TraceEntry->Params[3]
  327. );
  328. break;
  329. case TL_COSENDPACKET:
  330. fprintf(outfile, "[% 10u] COSENDPKT: Pkt %x\n",
  331. TraceEntry->Time,
  332. TraceEntry->Params[0]
  333. );
  334. break;
  335. case TL_COSENDCMPLTIN:
  336. fprintf(outfile, "[% 10u] COSENDCMPLTIN: Pkt %x Status %x\n",
  337. TraceEntry->Time,
  338. TraceEntry->Params[0],
  339. TraceEntry->Params[1]
  340. );
  341. break;
  342. case TL_COSENDCMPLTOUT:
  343. fprintf(outfile, "[% 10u] COSENDCMPLTOUT: Pkt %x\n",
  344. TraceEntry->Time,
  345. TraceEntry->Params[0]
  346. );
  347. break;
  348. case TL_CORECVPACKET:
  349. fprintf(outfile, "[% 10u] CORECVPKT: Pkt %x Vc %x\n",
  350. TraceEntry->Time,
  351. TraceEntry->Params[0],
  352. TraceEntry->Params[1]
  353. );
  354. break;
  355. case TL_CORETNPACKET:
  356. fprintf(outfile, "[% 10u] CORETNPKT: Pkt %x\n",
  357. TraceEntry->Time,
  358. TraceEntry->Params[0]
  359. );
  360. break;
  361. case TL_MINDPACKET:
  362. fprintf(outfile, "[% 10u] MINDPKT: Pkt %x\n",
  363. TraceEntry->Time,
  364. TraceEntry->Params[0]
  365. );
  366. break;
  367. case TL_MRETNPACKET:
  368. fprintf(outfile, "[% 10u] MRETNPKT: Pkt %x\n",
  369. TraceEntry->Time,
  370. TraceEntry->Params[0]
  371. );
  372. break;
  373. case TL_NDISPACKET:
  374. fprintf(outfile, "[% 10u] NDISPKT: %x Cnt %d Len %d Bufs %x %x %x %x %x\n",
  375. TraceEntry->Time,
  376. TraceEntry->Params[0],
  377. TraceEntry->Params[1],
  378. TraceEntry->Params[2],
  379. TraceEntry->Params[3],
  380. TraceEntry->Params[4],
  381. TraceEntry->Params[5],
  382. TraceEntry->Params[6],
  383. TraceEntry->Params[7]
  384. );
  385. break;
  386. default:
  387. params = TL_GET_PARAM_COUNT(TraceEntry->EventId);
  388. fprintf(outfile, "****: Unknown Event ID %d with %d Params: ",
  389. TL_GET_EVENT(TraceEntry->EventId), params);
  390. for (i = 0; i < params; i++)
  391. fprintf(outfile, "%x ", TraceEntry->Params[i]);
  392. fprintf(outfile, "\n");
  393. break;
  394. }
  395. }
  396. // ======================================================================