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.

428 lines
13 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. reducer.c
  5. Abstract:
  6. Trace Reducer Tool
  7. Author:
  8. 08-Apr-1998 mraghu
  9. Revision History:
  10. --*/
  11. //#define _UNICODE
  12. //#define UNICODE
  13. #include <stdlib.h>
  14. #include <stdio.h>
  15. #include <nt.h>
  16. #include <ntrtl.h>
  17. #include <nturtl.h>
  18. #include <wtypes.h>
  19. #include "cpdapi.h"
  20. #define MAXSTR 1024
  21. #define MAXLOGFILES 16
  22. void ReducerUsage()
  23. {
  24. printf("Usage: reducer [Options] <EtlFile1 EtlFile2 ...> | [-h | -help | -?]\n");
  25. printf("\t-out <filename> Output file name. Default is Workload.txt\n");
  26. printf("\t-h \n");
  27. printf("\t-help \n");
  28. printf("\t-? Display usage information\n");
  29. // printf("\t-start <time-stamp> Start Time\n");
  30. // printf("\t-end <time-stamp> End Time\n");
  31. // printf("\t <time-stamp> can be found in tracedmp result\n");
  32. // printf("\n");
  33. // printf("\t-base Original reducer report (default report)\n");
  34. // printf("\t-file Hot File Report\n");
  35. // printf("\t-pf page fault report\n");
  36. // printf("\t -summary processes summary of faults per process (default PF report).\n");
  37. // printf("\t modules summary of faults per module.\n");
  38. // printf("\t -process <image name> rundown for specific process.\n");
  39. // printf("\t all\n");
  40. // printf("\t -module <module name> rundown for specific modules.\n");
  41. // printf("\t all\n");
  42. // printf("\t -sort ALL sort by all fault total.\n");
  43. // printf("\t HPF sort by HPF fault total.\n");
  44. // printf("\t TF sort by TF fault total.\n");
  45. // printf("\t DZF sort by DZF fault total.\n");
  46. // printf("\t COW sort by COW fault total.\n");
  47. // printf("\n");
  48. // printf("\tNote: (1) Cannot generate HotFile Report and PageFault Report\n");
  49. // printf("\t at the same time\n");
  50. // printf("\t0x%08X,%d,\n", STATUS_SEVERITY_WARNING, RtlNtStatusToDosError(STATUS_SEVERITY_WARNING));
  51. }
  52. void stowc(char *str, WCHAR *wstr)
  53. {
  54. int len, i;
  55. PUCHAR AnsiChar;
  56. len = strlen(str);
  57. for (i = 0; i < len; i++)
  58. {
  59. AnsiChar = &str[i];
  60. wstr[i] = RtlAnsiCharToUnicodeChar(&AnsiChar);
  61. }
  62. wstr[len] = 0;
  63. }
  64. ULONGLONG
  65. ParseTimeString(char * strTime)
  66. {
  67. #if 0
  68. CHAR lstrTime[25];
  69. PCHAR strYear, strMonth, strDate,
  70. strHour, strMinute, strSecond, strMilliSecond;
  71. LARGE_INTEGER largeTime;
  72. FILETIME localTime, stdTime;
  73. SYSTEMTIME sysTime;
  74. if (strTime == NULL)
  75. return (ULONGLONG) 0;
  76. strcpy(lstrTime, strTime);
  77. strMonth = lstrTime;
  78. for (strDate = strMonth;
  79. *strDate && *strDate >= '0' && *strDate <= '9';
  80. strDate ++);
  81. *strDate = '\0';
  82. strDate ++;
  83. for (strYear = strDate;
  84. *strYear && *strYear >= '0' && *strYear <= '9';
  85. strYear ++);
  86. *strYear = '\0';
  87. strYear ++;
  88. for (strHour = strYear;
  89. *strHour && *strHour >= '0' && *strHour <= '9';
  90. strHour ++);
  91. *strHour = '\0';
  92. strHour ++;
  93. for (strMinute = strHour;
  94. *strMinute && *strMinute >= '0' && *strMinute <= '9';
  95. strMinute ++);
  96. *strMinute = '\0';
  97. strMinute ++;
  98. for (strSecond = strMinute;
  99. *strSecond && *strSecond >= '0' && *strSecond <= '9';
  100. strSecond ++);
  101. *strSecond = '\0';
  102. strSecond ++;
  103. for (strMilliSecond = strSecond;
  104. *strMilliSecond && *strMilliSecond >= '0' && *strMilliSecond <= '9';
  105. strMilliSecond ++);
  106. *strMilliSecond = '\0';
  107. strMilliSecond ++;
  108. sysTime.wYear = atoi(strYear);
  109. sysTime.wMonth = atoi(strMonth);
  110. sysTime.wDay = atoi(strDate);
  111. sysTime.wHour = atoi(strHour);
  112. sysTime.wMinute = atoi(strMinute);
  113. sysTime.wSecond = atoi(strSecond);
  114. sysTime.wMilliseconds = atoi(strMilliSecond);
  115. SystemTimeToFileTime(&sysTime, &localTime);
  116. LocalFileTimeToFileTime(&localTime, &stdTime);
  117. largeTime.HighPart = stdTime.dwHighDateTime;
  118. largeTime.LowPart = stdTime.dwLowDateTime;
  119. return (ULONGLONG) largeTime.QuadPart;
  120. #else
  121. ULONGLONG TimeStamp = 0;
  122. ULONG i = 0;
  123. for (i = 0; strTime[i] != '\0'; i ++)
  124. {
  125. TimeStamp = TimeStamp * 10 + (strTime[i] - '0');
  126. }
  127. return TimeStamp;
  128. #endif
  129. }
  130. VOID
  131. ProcessTrace(
  132. IN ULONG LogFileCount,
  133. IN LPCSTR * LogFileName,
  134. IN ULONGLONG StartTime,
  135. IN ULONGLONG EndTime,
  136. IN ULONGLONG DSStartTime,
  137. IN ULONGLONG DSEndTime,
  138. IN ULONG MoreFlags,
  139. IN PVOID pUserContext,
  140. IN LPSTR pOutFileName
  141. )
  142. {
  143. // Call TraceLib and process it.
  144. //
  145. TRACE_BASIC_INFO TraceBasicInfo;
  146. memset(&TraceBasicInfo, 0, sizeof(TRACE_BASIC_INFO));
  147. TraceBasicInfo.Flags = TRACE_REDUCE | MoreFlags;
  148. TraceBasicInfo.LogFileName = LogFileName;
  149. TraceBasicInfo.LogFileCount = LogFileCount;
  150. TraceBasicInfo.pUserContext = pUserContext;
  151. TraceBasicInfo.StartTime = StartTime;
  152. TraceBasicInfo.EndTime = EndTime;
  153. TraceBasicInfo.DSStartTime = DSStartTime;
  154. TraceBasicInfo.DSEndTime = DSEndTime;
  155. TraceBasicInfo.ProcFileName = pOutFileName;
  156. InitTraceContext(&TraceBasicInfo);
  157. DeinitTraceContext(&TraceBasicInfo);
  158. }
  159. void __cdecl main(int argc ,char * argv[])
  160. {
  161. LPCSTR LogFileName = "C:\\perflogs\\perfdata_980406.blg";
  162. CHAR TraceLogFile[MAXSTR];
  163. WCHAR PerfLogFile[MAXSTR];
  164. BOOLEAN bTrace = FALSE;
  165. LPCSTR EvmFile[MAXLOGFILES];
  166. ULONGLONG StartTime = 0, EndTime = 0;
  167. ULONG i;
  168. ULONG LogFileCount = 0;
  169. ULONG flagsMore = 0;
  170. PVOID pUserContext = NULL;
  171. CPD_USER_CONTEXT_MM UserContextMM;
  172. UserContextMM.reportNow = REPORT_SUMMARY_PROCESS;
  173. UserContextMM.sortNow = REPORT_SORT_ALL;
  174. UserContextMM.strImgName = NULL;
  175. memset(&TraceLogFile, 0, sizeof(CHAR) * MAXSTR);
  176. while (--argc > 0)
  177. {
  178. ++argv;
  179. if (**argv == '-' || **argv == '/')
  180. {
  181. ** argv = '-';
  182. if (!_stricmp(argv[0], "-out"))
  183. {
  184. if (argc > 1)
  185. {
  186. CHAR TempStr[MAXSTR];
  187. strcpy(TempStr, argv[1]);
  188. //stowc(argv[1], TempStr);
  189. ++argv; --argc;
  190. _fullpath(TraceLogFile, TempStr, MAXSTR);
  191. printf("Setting output file to: '%s'\n", TraceLogFile);
  192. bTrace = TRUE;
  193. }
  194. }
  195. else if (!_stricmp(argv[0], "-start"))
  196. {
  197. if (argc > 1)
  198. {
  199. flagsMore |= TRACE_DS_ONLY | TRACE_LOG_REPORT_BASIC;
  200. StartTime = ParseTimeString(argv[1]);
  201. argc --; argv ++;
  202. }
  203. }
  204. else if (!_stricmp(argv[0], "-end"))
  205. {
  206. if (argc > 1)
  207. {
  208. flagsMore |= TRACE_DS_ONLY | TRACE_LOG_REPORT_BASIC;
  209. EndTime = ParseTimeString(argv[1]);
  210. argc --; argv ++;
  211. }
  212. }
  213. else if (!_stricmp(argv[0], "-base"))
  214. {
  215. flagsMore |= TRACE_LOG_REPORT_BASIC;
  216. }
  217. else if (!_stricmp(argv[0], "-total"))
  218. {
  219. flagsMore |= TRACE_LOG_REPORT_TOTALS;
  220. }
  221. else if (!_stricmp(argv[0], "-file"))
  222. {
  223. flagsMore |= TRACE_LOG_REPORT_FILE;
  224. if (argc > 1 && argv[1][0] >= '0' && argv[1][0] <= '9')
  225. {
  226. (ULONG) pUserContext = atoi(argv[1]);
  227. argc --; argv ++;
  228. }
  229. else
  230. {
  231. (ULONG) pUserContext = DEFAULT_FILE_REPORT_SIZE;
  232. }
  233. }
  234. else if (!_stricmp(argv[0], "-hpf"))
  235. {
  236. flagsMore |= TRACE_LOG_REPORT_HARDFAULT;
  237. }
  238. else if (!_stricmp(argv[0], "-pf"))
  239. {
  240. flagsMore |= TRACE_LOG_REPORT_MEMORY;
  241. pUserContext = (PVOID) & UserContextMM;
  242. }
  243. else if (!_stricmp(argv[0], "-summary"))
  244. {
  245. if (argc > 1)
  246. {
  247. flagsMore |= TRACE_LOG_REPORT_MEMORY;
  248. pUserContext = (PVOID) & UserContextMM;
  249. if (!_stricmp(argv[1], "processes"))
  250. {
  251. argc --; argv ++;
  252. UserContextMM.reportNow = REPORT_SUMMARY_PROCESS;
  253. }
  254. else if (!_stricmp(argv[1], "modules"))
  255. {
  256. argc --; argv ++;
  257. UserContextMM.reportNow = REPORT_SUMMARY_MODULE;
  258. }
  259. }
  260. }
  261. else if (!_stricmp(argv[0], "-process"))
  262. {
  263. flagsMore |= TRACE_LOG_REPORT_MEMORY;
  264. pUserContext = (PVOID) & UserContextMM;
  265. UserContextMM.reportNow = REPORT_LIST_PROCESS;
  266. if ((argc > 1) && (argv[1][0] != '-' || argv[1][0] != '/'))
  267. {
  268. if (_stricmp(argv[1], "all"))
  269. {
  270. UserContextMM.strImgName =
  271. malloc(sizeof(WCHAR) * (strlen(argv[1]) + 1));
  272. if (UserContextMM.strImgName)
  273. {
  274. stowc(argv[1], UserContextMM.strImgName);
  275. }
  276. }
  277. argc --; argv ++;
  278. }
  279. }
  280. else if (!_stricmp(argv[0], "-module"))
  281. {
  282. flagsMore |= TRACE_LOG_REPORT_MEMORY;
  283. pUserContext = (PVOID) & UserContextMM;
  284. UserContextMM.reportNow = REPORT_LIST_MODULE;
  285. if ((argc > 1) && (argv[1][0] != '-' || argv[1][0] != '/'))
  286. {
  287. if (_stricmp(argv[1], "all"))
  288. {
  289. UserContextMM.strImgName =
  290. malloc(sizeof(WCHAR) * (strlen(argv[1]) + 1));
  291. if (UserContextMM.strImgName)
  292. {
  293. stowc(argv[1], UserContextMM.strImgName);
  294. }
  295. }
  296. argc --; argv ++;
  297. }
  298. }
  299. else if (!_stricmp(argv[0], "-sort"))
  300. {
  301. flagsMore |= TRACE_LOG_REPORT_MEMORY;
  302. pUserContext = (PVOID) & UserContextMM;
  303. if ((argc > 1) && (argv[1][0] != '-' || argv[1][0] != '/'))
  304. {
  305. if (!_stricmp(argv[1], "hpf"))
  306. {
  307. UserContextMM.sortNow = REPORT_SORT_HPF;
  308. }
  309. else if (!_stricmp(argv[1], "tf"))
  310. {
  311. UserContextMM.sortNow = REPORT_SORT_TF;
  312. }
  313. else if (!_stricmp(argv[1], "dzf"))
  314. {
  315. UserContextMM.sortNow = REPORT_SORT_DZF;
  316. }
  317. else if (!_stricmp(argv[1], "cow"))
  318. {
  319. UserContextMM.sortNow = REPORT_SORT_COW;
  320. }
  321. else
  322. {
  323. UserContextMM.sortNow = REPORT_SORT_ALL;
  324. }
  325. argc --; argv ++;
  326. }
  327. }
  328. else
  329. {
  330. goto Usage;
  331. }
  332. }
  333. else
  334. {
  335. LPCSTR pLogFile;
  336. pLogFile = malloc(sizeof(CHAR) * MAXSTR);
  337. RtlZeroMemory((char *) pLogFile, sizeof(CHAR) * MAXSTR);
  338. EvmFile[LogFileCount] = pLogFile;
  339. strcpy((char *) EvmFile[LogFileCount ++], argv[0]);
  340. bTrace = TRUE;
  341. printf("LogFile %s\n", (char *) EvmFile[LogFileCount - 1]);
  342. }
  343. }
  344. if (LogFileCount == 0)
  345. {
  346. goto Usage;
  347. }
  348. if (flagsMore == 0)
  349. {
  350. flagsMore |= TRACE_LOG_REPORT_BASIC;
  351. }
  352. if ( (flagsMore & TRACE_LOG_REPORT_MEMORY)
  353. && (flagsMore & TRACE_LOG_REPORT_FILE))
  354. {
  355. printf("Error: cannot generate HotFile report and PageFault report at the same time.\n");
  356. goto Cleanup;
  357. }
  358. if (bTrace)
  359. {
  360. ProcessTrace(LogFileCount, EvmFile, (ULONGLONG) 0, (ULONGLONG) 0,
  361. StartTime, EndTime, flagsMore, pUserContext, TraceLogFile);
  362. }
  363. for (i=0; i < LogFileCount; i++)
  364. {
  365. free((char*)EvmFile[i]);
  366. }
  367. if (UserContextMM.strImgName)
  368. {
  369. free(UserContextMM.strImgName);
  370. }
  371. Cleanup:
  372. return;
  373. Usage:
  374. ReducerUsage();
  375. goto Cleanup;
  376. }