internal ReportForm([NotNull] MainForm f) { this.f = f; this.graphtype = f.graphtype; if (!f.noUI) { InitializeComponent(); } try { buildReports(); } catch (Exception e) { throw new Exception(e.Message + "\n"); } }
internal ReportForm(MainForm f) { this.f = f; this.runaswindow = f.runaswindow; this.graphtype = f.graphtype; if( runaswindow) { InitializeComponent(); } try { buildReports(); } catch(Exception e) { throw new Exception(e.Message + "\n"); } }
private void ShowUsage() { graphtype = Graph.GraphType.Invalid; String s = ""; s += String.Format("Usage: {0} -attach PID [-o logName] [-t timeoutInMiliseconds]\r\n", Path.GetFileName(Application.ExecutablePath)); s += " -attach PID \t- attaches to the target process\r\n"; s += " -o logName \t- file to write the resulting profile log to\r\n"; s += " -t timeout \t- max time in miliseconds to wait for the attach to succeed\r\n"; s += "or\r\n"; s += String.Format("{0} -detach PID\r\n", Path.GetFileName(Application.ExecutablePath)); s += " -detach PID \t- detaches from the target process (use -attach first)\r\n"; s += "or\r\n"; s += String.Format("{0} -dumpheap PID\r\n", Path.GetFileName(Application.ExecutablePath)); s += " -dumpheap PID \t- triggers a GC and dumps the GC heap in the target process (use -attach first)\r\n"; s += "or\r\n"; s += String.Format("{0} -o logName [-na] [-nc] -[np] [-target V4DesktopCLR|V4CoreCLR|V2DesktopCLR] -u URL\r\n", Path.GetFileName(Application.ExecutablePath)); s += " -u URL\t- URL to profile (must go at the end)\r\n"; s += " -o logName\t- file to write the resulting profile log to\r\n"; s += " -na\t\t- don't record allocations\r\n"; s += " -nc\t\t- don't record calls\r\n"; s += " -np\t\t- start with profiling active off\r\n"; s += " -target V4DesktopCLR|V4CoreCLR|V2DesktopCLR\t- specify the target CLR runtime to be profiled (V4DesktopCLR is the default choice)\r\n"; s += "or\r\n"; s += String.Format("{0} [-o logName] [-na] [-nc] -[np] [-target V4DesktopCLR|V4CoreCLR|V2DesktopCLR] -p exeName [args]\r\n", Path.GetFileName(Application.ExecutablePath)); s += " -p exeName args\t- application to profile and its arguments (must go at the end)\r\n"; s += " -o logName\t- file to write the resulting profile log to\r\n"; s += " -na\t\t- don't record allocations\r\n"; s += " -nc\t\t- don't record calls\r\n"; s += " -np\t\t- start with profiling active off\r\n"; s += " -target V4DesktopCLR|V4CoreCLR|V2DesktopCLR\t- specify the target CLR runtime to be profiled (V4DesktopCLR is the default choice)\r\n"; s += "or\r\n"; s += String.Format("{0} -a -l logName [-b <start marker>] [-e <end marker>]\r\n", Path.GetFileName(Application.ExecutablePath)); s += " -a \t - asks for an allocation report\r\n"; s += " -l logName \t - names the input log file\r\n"; s += " -b <start marker>\t - only report allocations after this log file comment\r\n"; s += " -e <end marker> \t - only report allocations before this log file comment\r\n"; s += "or\r\n"; s += String.Format("{0} -r -l logName [-b <start marker>] [-e <end marker>]\r\n", Path.GetFileName(Application.ExecutablePath)); s += " -r \t - asks for a relocation report\r\n"; s += " -l logName \t - names the input log file\r\n"; s += " -b <start marker>\t - only report relocations after this log file comment\r\n"; s += " -e <end marker> \t - only report relocations before this log file comment\r\n"; s += "or\r\n"; s += String.Format("{0} -s -l logName [-b <start marker>] [-e <end marker>] [-t <time marker]\r\n", Path.GetFileName(Application.ExecutablePath)); s += " -s \t - asks for a surviving objects report\r\n"; s += " -l logName \t - names the input log file\r\n"; s += " -b <start marker>\t - only report objects allocated after this log file comment\r\n"; s += " -e <end marker> \t - only report objects allocated before this log file comment\r\n"; s += " -t <time marker> \t - report survivors at this log file comment\r\n"; s += "or\r\n"; s += String.Format("{0} -[c]f -l logName [-b <start marker>] [-e <end marker>]\r\n", Path.GetFileName(Application.ExecutablePath)); s += " -[c]f \t - asks for a [critical] finalizer report\r\n"; s += " -l logName \t - names the input log file\r\n"; s += " -b <start marker>\t - only report finalizers queued after this log file comment\r\n"; s += " -e <end marker> \t - only report finalizers queued before this log file comment\r\n"; s += "or\r\n"; s += String.Format("{0} -sd -l logName [-b <start marker>] [-e <end marker>]\r\n", Path.GetFileName(Application.ExecutablePath)); s += " -sd \t - asks for a survivor difference report\r\n"; s += " -l logName \t - names the input log file\r\n"; s += " -b <start marker>\t - first instant in time to gather survivors\r\n"; s += " -e <end marker> \t - second instant in time to compare survivorship agains\r\n"; s += "or\r\n"; s += String.Format("{0} -h -l logName [-b <start marker>] [-e <end marker>]\r\n", Path.GetFileName(Application.ExecutablePath)); s += " -h \t - asks for a heap dump report\r\n"; s += " -l logName \t - names the input log file\r\n"; s += " -b <start marker>\t - only report heap dumps after this log file comment\r\n"; s += " -e <end marker> \t - only report heap dumps before this log file comment\r\n"; s += " \t - (giving only -b reports the first heap after the log file comment)\r\n"; s += "or\r\n"; s += String.Format("{0} -c -l logName\r\n", Path.GetFileName(Application.ExecutablePath)); s += " -c \t - asks for a list of the comments in the input log file\r\n"; s += "or\r\n"; s += String.Format("{0} -lr -l logName [-b <start marker>] [-e <end marker>]\r\n", Path.GetFileName(Application.ExecutablePath)); s += "Where\r\n"; s += " -lr \t - asks for a leak report\r\n"; s += " -l logName \t - names the input log file\r\n"; s += " -b <start marker>\t - only report allocations after this log file comment\r\n"; s += " -e <end marker> \t - only report allocations before this log file comment\r\n"; s += "or\r\n"; s += String.Format("{0} -diff [-lo OldlogName -ln NewlogName] [-ld DifflogName][-w]\r\n", Path.GetFileName(Application.ExecutablePath)); s += "Where\r\n"; s += " -diff \t- asks for a difference report\r\n"; s += " -lo logName \t- old resulting profile log file\r\n"; s += " -ln logName \t- new resulting profile log file\r\n"; s += " -ld logName \t- diff result of old and new profile log file\r\n"; s += " -w \t- run as window (otherwise textual report)\r\n"; if (noUI) { Console.Write(s); } else { HelpForm helpForm = new HelpForm(); helpForm.helpText.Text = s; helpForm.ShowDialog(); } return; }
private void viewComparisonMenuItem_Click(object sender, System.EventArgs e) { currlogFileName = this.logFileName; OpenFileDialog openFileDialog1 = new OpenFileDialog(); openFileDialog1.FileName = "*.log"; openFileDialog1.Filter = "Allocation Logs | *.log"; if (openFileDialog1.ShowDialog() == DialogResult.OK && openFileDialog1.CheckFileExists) { prevlogFileName = openFileDialog1.FileName; } this.noUI = false; graphtype = Graph.GraphType.AllocationGraph; try { ReportForm _MgrForm = new ReportForm(this); _MgrForm.Visible = true; } catch { /* errors already told user, so continue. */ } }
public MainForm(string[] arguments) { int i; string logFileName = ""; bool onlyCreateLog = false; processFileName = null; windowsStoreAppProfileeInfo = null; profileAllocations = profileCalls = profilingActive = true; //Check ProfilerOBJ.DLL exist first if (!File.Exists( getProfilerFullPath() ) ) { ShowErrorMessage("Can not find '" + getProfilerFullPath() + "', please make sure ProfilerOBJ.dll exists at the same directory as CLRProfiler.exe."); Environment.ExitCode = 1; exitProgram = true; return; } #region arguments if (arguments.Length > 0) { int pid; Environment.ExitCode = 0; switch (arguments[0]) { case "-attach": case "/attach": exitProgram = true; if ((pid = getPID(arguments)) == 0) { Environment.ExitCode = 1; return; } for (int index = 2; index + 1 < arguments.Length; index = index+2) { if (arguments[index] == "-o" || arguments[index] == "/o") { string fullPath = Path.GetFullPath(arguments[index+1]); logDirectory = Path.GetDirectoryName(fullPath); nameToUse = Path.GetFileName(fullPath); } if (arguments[index] == "-t" || arguments[index] == "/t") { maxWaitingTimeInMiliseconds = UInt32.Parse(arguments[index + 1]); if (maxWaitingTimeInMiliseconds < 3000) { maxWaitingTimeInMiliseconds = 3000; ShowErrorMessage("CLRProfiler must wait a minimum of 3000 milliseconds before it will time out while attaching to the application."); } } } if(logDirectory == null) { logDirectory = Directory.GetCurrentDirectory(); } /* basic initialization stuff */ CreatePipe(@"\\.\pipe\OMV_PIPE", false, ref handshakingPipeHandle, ref handshakingPipe); CreatePipe(@"\\.\pipe\OMV_LOGGING_PIPE", false, ref loggingPipeHandle, ref loggingPipe); instance = this; if (attachProfiler(pid, GetLogFullPath(pid)) ) { Console.WriteLine("The logging data is saved at " + GetLogFullPath(pid) + "."); } else { Environment.ExitCode = 1; } ClearProfiledProcessInfo(); return; case "-detach": case "/detach": exitProgram = true; if ((pid = getPID(arguments)) == 0) { Environment.ExitCode = 1; return; } if (!InitWindowsStoreAppProfileeInfoIfNecessary(pid)) return; if (!isProfilerLoaded(pid)) { Console.WriteLine("PID argument is not valid."); Environment.ExitCode = 1; return; } CreateEvents(pid); SendDetachRequest(); Console.WriteLine("Detach is sucessfully requested."); Console.WriteLine("It may take a while for CLRProfiler to be unloaded completely. "); Console.WriteLine("You may look for profiler detach event from the event log to determine if detach succeeds."); ClearProfiledProcessInfo(); return; case "-dumpheap": case "/dumpheap": exitProgram = true; if ((pid = getPID(arguments)) == 0) { Environment.ExitCode = 1; return; } if (!InitWindowsStoreAppProfileeInfoIfNecessary(pid)) return; if (!isProfilerLoaded(pid)) { Console.WriteLine("PID argument is not valid."); Environment.ExitCode = 1; return; } CreateEvents(pid); forceGcCompletedEvent.Wait(1); forceGcCompletedEvent.Reset(); forceGcEvent.Set(); Console.WriteLine(Path.GetFileName(Application.ExecutablePath) + " is waiting up to 10 minutes for target process to finish dumping the GC heap."); if (forceGcCompletedEvent.Wait(10 * 60 * 1000)) { forceGcCompletedEvent.Reset(); Console.WriteLine("A heap dump is appended in the log file."); } else { Console.WriteLine("There was no response from the target process."); Environment.ExitCode = 1; } ClearEvents(); ClearProfiledProcessInfo(); return; } } #endregion arguments #region arguments2 for (i = 0; i < arguments.Length && !onlyCreateLog; i++) { switch (arguments[i]) { case "-target": case "/target": string version = FetchArgument(arguments, ref i); if (String.Compare(version, "V4DesktopCLR", true) == 0) targetCLRVersion = CLRSKU.V4DesktopCLR; else if (String.Compare(version, "V4CoreCLR", true) == 0) targetCLRVersion = CLRSKU.V4CoreCLR; else if (String.Compare(version, "V2DesktopCLR", true) == 0) targetCLRVersion = CLRSKU.V2DesktopCLR; else { CommandLineError("No matched target CLR version."); help = true; } break; case "-u": case "/u": if (logFileName == null) { CommandLineError("A log filename needs to be specified with -o beofre -u argument"); help = true; } else { profilingURL = FetchArgument(arguments, ref i); if (profilingURL != null) onlyCreateLog = true; } break; case "-na": case "/na": profileAllocations = false; break; case "-nc": case "/nc": profileCalls = false; break; case "-np": case "/np": profilingActive = false; break; case "/ns": case "-ns": trackCallStacks = false; break; case "-o": case "/o": logFileName = FetchArgument(arguments, ref i); break; case "-p": case "/p": processFileName = FetchArgument(arguments, ref i); if (processFileName != null) onlyCreateLog = true; break; case "-diff": case "/diff": graphtype = Graph.GraphType.AllocationGraph; break; case "-lo": case "/lo": prevlogFileName = FetchArgument(arguments, ref i); break; case "-ln": case "/ln": currlogFileName = FetchArgument(arguments, ref i); break; case "-ld": case "/ld": difflogFileName = FetchArgument(arguments, ref i); break; case "-l": case "/l": logFileName = FetchArgument(arguments, ref i); break; case "-a": case "/a": reportKind = ReportKind.AllocationReport; break; case "-r": case "/r": reportKind = ReportKind.RelocationReport; break; case "-s": case "/s": reportKind = ReportKind.SurvivorReport; break; case "-sd": case "/sd": reportKind = ReportKind.SurvivorDifferenceReport; break; case "-h": case "/h": reportKind = ReportKind.HeapDumpReport; break; case "-lr": case "/lr": reportKind = ReportKind.LeakReport; break; case "-f": case "/f": reportKind = ReportKind.FinalizerReport; break; case "-cf": case "/cf": reportKind = ReportKind.CriticalFinalizerReport; break; case "-c": case "/c": reportKind = ReportKind.CommentReport; break; case "-b": case "/b": startMarker = FetchArgument(arguments, ref i); break; case "-e": case "/e": endMarker = FetchArgument(arguments, ref i); break; case "-t": case "/t": do { string[] newTimeMarker = new String[timeMarker.Length + 1]; for (int j = 0; j < timeMarker.Length; j++) newTimeMarker[j] = timeMarker[j]; newTimeMarker[timeMarker.Length] = FetchArgument(arguments, ref i); timeMarker = newTimeMarker; } while (i + 1 < arguments.Length && arguments[i + 1][0] != '-' && arguments[i + 1][0] != '/'); break; case "-w": case "/w": this.noUI = false; break; case "-?": case "/?": case "-help": case "/help": help = true; break; case "-gc": case "/gc": gcOnLogFileComments = true; break; default: if (arguments[i][0] == '-' || arguments[i][0] == '/') CommandLineError("Unrecognized option {0}", arguments[i]); else if (File.Exists(arguments[i])) logFileName = arguments[i]; else CommandLineError("Log file {0} not found", arguments[i]); break; } } #endregion arguments2 #region AllocationGraph if (graphtype == Graph.GraphType.AllocationGraph) { if (File.Exists(prevlogFileName) && File.Exists(currlogFileName)) { viewdiff = true; return; } else { String s = ""; if (!File.Exists(prevlogFileName)) { s += String.Format("Previous build log File not exists or command line missing -lo. \n"); } if (!File.Exists(currlogFileName)) { s += String.Format("New build log file not exists or command line missing -ln \n"); } CommandLineError(s); } } #endregion AllocationGraph #region NoReport else if (reportKind != ReportKind.NoReport) { if (logFileName == "") CommandLineError("Need -l logFileName for report"); else if (!File.Exists(logFileName)) CommandLineError("Log file {0} not found", logFileName); else { switch (reportKind) { case ReportKind.AllocationReport: Reports.AllocationReport(logFileName, startMarker, endMarker); break; case ReportKind.RelocationReport: Reports.RelocationReport(logFileName, startMarker, endMarker); break; case ReportKind.SurvivorReport: Reports.SurvivorReport(logFileName, startMarker, endMarker, timeMarker); break; case ReportKind.SurvivorDifferenceReport: Reports.SurvivorDifferenceReport(logFileName, startMarker, endMarker); break; case ReportKind.HeapDumpReport: Reports.HeapDumpReport(logFileName, startMarker, endMarker); break; case ReportKind.LeakReport: Reports.LeakReport(logFileName, startMarker, endMarker); break; case ReportKind.FinalizerReport: Reports.FinalizerReport(false, logFileName, startMarker, endMarker); break; case ReportKind.CriticalFinalizerReport: Reports.FinalizerReport(true, logFileName, startMarker, endMarker); break; case ReportKind.CommentReport: Reports.CommentReport(logFileName); break; } } } #endregion NoReport else { if (onlyCreateLog) { /* treat everything after the exe name to profile as arguments */ for (; i < arguments.Length; i++) { commandLine += arguments[i] + ' '; } } /* basic initialization stuff */ CreatePipe(@"\\.\pipe\OMV_PIPE", false, ref handshakingPipeHandle, ref handshakingPipe); CreatePipe(@"\\.\pipe\OMV_LOGGING_PIPE", false, ref loggingPipeHandle, ref loggingPipe); instance = this; if (!onlyCreateLog) { /* standard UI operation */ if (help) { ShowUsage(); exitProgram = true; return; } noUI = false; // // Required for Windows Form Designer support // InitializeComponent(); // Set V4 Desktop CLR to be the default value targetCLRVersioncomboBox.SelectedIndex = 0; font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(204))); ; if (logFileName != "" && File.Exists(logFileName)) LoadLogFile(logFileName); EnableDisableViewMenuItems(); } else { /* command-line only */ noUI = true; exitProgram = true; try { string fileName = (logFileName == "" ? Path.ChangeExtension(processFileName, ".log") : logFileName); string fullPath = Path.GetFullPath(fileName); logDirectory = Path.GetDirectoryName(fullPath); nameToUse = Path.GetFileName(fileName); if (profilingURL == null) { startApplicationButton_Click(null, null); } else { startURLButton_Click(null, null); } if (profilerConnected) { Environment.ExitCode = 0; } else { Environment.ExitCode = 1; } while (profiledProcess != null && !ProfiledProcessHasExited()) Thread.Sleep(500); } catch (Exception e) { throw new Exception(e.Message + '\n' + e.StackTrace); // Console.WriteLine("There was a problem profiling {0}", processFileName); } } } }
internal void ViewGraph(ReadLogResult logResult, string exeName, Graph.GraphType graphType) { string fileName = log.fileName; if (exeName != null) { fileName = exeName; } Graph graph = null; string title = ""; switch (graphType) { case Graph.GraphType.CallGraph: graph = logResult.callstackHistogram.BuildCallGraph(new FilterForm()); graph.graphType = Graph.GraphType.CallGraph; title = "Call Graph for: "; break; case Graph.GraphType.AssemblyGraph: graph = logResult.callstackHistogram.BuildAssemblyGraph(new FilterForm()); graph.graphType = Graph.GraphType.AssemblyGraph; title = "Assembly Graph for: "; break; case Graph.GraphType.AllocationGraph: graph = logResult.allocatedHistogram.BuildAllocationGraph(new FilterForm()); graph.graphType = Graph.GraphType.AllocationGraph; title = "Allocation Graph for: "; break; case Graph.GraphType.HeapGraph: graph = logResult.objectGraph.BuildTypeGraph(new FilterForm()); title = "Heap Graph for: "; break; case Graph.GraphType.FunctionGraph: graph = logResult.functionList.BuildFunctionGraph(new FilterForm()); graph.graphType = Graph.GraphType.FunctionGraph; title = "Function Graph for: "; break; case Graph.GraphType.ModuleGraph: graph = logResult.functionList.BuildModuleGraph(new FilterForm()); graph.graphType = Graph.GraphType.ModuleGraph; title = "Module Graph for: "; break; case Graph.GraphType.ClassGraph: graph = logResult.functionList.BuildClassGraph(new FilterForm()); graph.graphType = Graph.GraphType.ClassGraph; title = "Class Graph for: "; break; default: Debug.Assert(false); break; } title += fileName; GraphViewForm graphViewForm = new GraphViewForm(graph, title); graphViewForm.Visible = true; }
private void readLogFile(ReadNewLog log, ReadLogResult logResult, string exeName, Graph.GraphType graphType) { log.ReadFile(logFileStartOffset, logFileEndOffset, logResult); //ViewGraph(logResult, exeName, graphType); }