private static int FindMarkerTickIndex(string marker, ReadNewLog log) { int result = -1; if (marker == CommentRangeForm.startCommentString) result = 0; else if (marker == CommentRangeForm.shutdownCommentString) result = log.maxTickIndex; else { for (int i = 0; i < log.commentEventList.count; i++) { if (log.commentEventList.eventString[i] == marker) result = log.commentEventList.eventTickIndex[i]; } } if (result == -1) { double time; if (double.TryParse(marker, System.Globalization.NumberStyles.Float, null, out time)) { result = log.TimeToTickIndex(time); } else { Console.WriteLine("Marker {0} not found", marker); return 0; } } return result; }
public void readLogFile() { log = new ReadNewLog(logFileName); logResult = GetLogResult(); log.ReadFile(logFileStartOffset, logFileEndOffset, logResult); }
internal ViewCommentsForm(ReadNewLog log) { // // Required for Windows Form Designer support // InitializeComponent(); string[] lines = new string[log.commentEventList.count]; for (int i = 0; i < log.commentEventList.count; i++) lines[i] = string.Format("{0} ({1:f3} secs)", log.commentEventList.eventString[i], log.TickIndexToTime(log.commentEventList.eventTickIndex[i])); this.commentTextBox.Lines = lines; }
private static ReadLogResult GetLogResult(ReadNewLog log) { ReadLogResult readLogResult = new ReadLogResult(); readLogResult.liveObjectTable = new LiveObjectTable(log); readLogResult.sampleObjectTable = new SampleObjectTable(log); readLogResult.allocatedHistogram = new Histogram(log); readLogResult.callstackHistogram = new Histogram(log); readLogResult.relocatedHistogram = new Histogram(log); readLogResult.finalizerHistogram = new Histogram(log); readLogResult.criticalFinalizerHistogram = new Histogram(log); readLogResult.objectGraph = new ObjectGraph(log, 0); readLogResult.functionList = new FunctionList(log); readLogResult.hadCallInfo = readLogResult.hadAllocInfo = false; readLogResult.heapDumpHistograms = new Histogram[0]; return readLogResult; }
internal static void SurvivorDifferenceReport(string logFileName, string startMarker, string endMarker) { // first read the entire file ReadNewLog log = new ReadNewLog(logFileName, false); ReadLogResult entireLogResult = GetLogResult(log); log.ReadFile(0, long.MaxValue, entireLogResult); if (startMarker == null) startMarker = CommentRangeForm.startCommentString; if (endMarker == null) endMarker = CommentRangeForm.shutdownCommentString; int startTickIndex = FindMarkerTickIndex(startMarker, log); int endTickIndex = FindMarkerTickIndex(endMarker, log); Histogram startHistogram = GetSurvivorHistogram(log, entireLogResult, 0, int.MaxValue, startMarker); Histogram endHistogram = GetSurvivorHistogram(log, entireLogResult, 0, int.MaxValue, endMarker); Console.WriteLine("Difference in surviving objects for {0} between {1} ({2} secs) and {3} ({4} secs)", logFileName, startMarker, log.TickIndexToTime(startTickIndex), endMarker, log.TickIndexToTime(endTickIndex)); WriteReport(startHistogram, endHistogram); }
private void readLogFile(ReadNewLog log, ReadLogResult logResult, string exeName, Graph.GraphType graphType) { log.ReadFile(logFileStartOffset, logFileEndOffset, logResult); ViewGraph(logResult, exeName, graphType); }
internal static void SurvivorReport(string logFileName, string startMarker, string endMarker, string[] timeMarker) { // first read the entire file ReadNewLog log = new ReadNewLog(logFileName, false); ReadLogResult entireLogResult = GetLogResult(log); log.ReadFile(0, long.MaxValue, entireLogResult); if (startMarker == null) startMarker = CommentRangeForm.startCommentString; if (endMarker == null) endMarker = CommentRangeForm.shutdownCommentString; int startTickIndex = FindMarkerTickIndex(startMarker, log); int endTickIndex = FindMarkerTickIndex(endMarker, log); if (timeMarker == null || timeMarker.Length == 0) { timeMarker = new String[1]; timeMarker[0] = CommentRangeForm.shutdownCommentString; } Histogram[] histogram = new Histogram[timeMarker.Length]; Console.Write("Surviving objects for {0} allocated between {1} ({2} secs) and {3} ({4} secs) at", logFileName, startMarker, log.TickIndexToTime(startTickIndex), endMarker, log.TickIndexToTime(endTickIndex)); string separator = ""; for (int i = 0; i < timeMarker.Length; i++) { if (timeMarker[i] == null) timeMarker[i] = CommentRangeForm.shutdownCommentString; histogram[i] = GetSurvivorHistogram(log, entireLogResult, startTickIndex, endTickIndex, timeMarker[i]); int timeTickIndex = FindMarkerTickIndex(timeMarker[i], log); Console.Write("{0} {1} ({2} secs) ", separator, timeMarker[i], log.TickIndexToTime(timeTickIndex)); separator = ","; } Console.WriteLine(); WriteReport(histogram, timeMarker); }
internal static Histogram GetSurvivorHistogram(ReadNewLog log, ReadLogResult entireLogResult, int startTickIndex, int endTickIndex, string timeMarker) { ReadLogResult logResult = entireLogResult; int timeTickIndex = entireLogResult.sampleObjectTable.lastTickIndex; if (timeMarker != null) { timeTickIndex = FindMarkerTickIndex(timeMarker, log); long endPos = log.TickIndexToPos(timeTickIndex); // Read the selected portion of the log again logResult = new ReadLogResult(); logResult.liveObjectTable = new LiveObjectTable(log); log.ReadFile(0, endPos, logResult); } Histogram histogram = new Histogram(log); LiveObjectTable.LiveObject o; for (logResult.liveObjectTable.GetNextObject(0, ulong.MaxValue, out o); o.id < ulong.MaxValue; logResult.liveObjectTable.GetNextObject(o.id + o.size, ulong.MaxValue, out o)) { if (startTickIndex <= o.allocTickIndex && o.allocTickIndex < endTickIndex) histogram.AddObject(o.typeSizeStacktraceIndex, 1); } return histogram; }
internal SampleObjectTable(ReadNewLog readNewLog) { masterTable = new SampleObject[initialFirstLevelLength][]; this.readNewLog = readNewLog; lastTickIndex = 0; gcTickList = null; }
internal LiveObjectTable(ReadNewLog readNewLog) { firstLevelTable = new ushort[initialFirstLevelLength][]; intervalTable = new IntervalTable(this); this.readNewLog = readNewLog; lastGcGen0Count = 0; lastGcGen1Count = 0; lastGcGen2Count = 0; lastTickIndex = 0; lastPos = 0; }
internal static void FinalizerReport(bool criticalFinalizers, string logFileName, string startMarker, string endMarker) { // first read the entire file ReadNewLog log = new ReadNewLog(logFileName, false); ReadLogResult entireLogResult = GetLogResult(log); log.ReadFile(0, long.MaxValue, entireLogResult); // if we were given a start or an end marker, we need to re-read a portion of the file. ReadLogResult logResult = entireLogResult; if (startMarker != null || endMarker != null) { int startTickIndex = 0; int endTickIndex = entireLogResult.sampleObjectTable.lastTickIndex; if (startMarker != null) startTickIndex = FindMarkerTickIndex(startMarker, log); if (endMarker != null) endTickIndex = FindMarkerTickIndex(endMarker, log); long startPos = log.TickIndexToPos(startTickIndex); long endPos = log.TickIndexToPos(endTickIndex); // Read the selected portion of the log again logResult = new ReadLogResult(); logResult.liveObjectTable = new LiveObjectTable(log); logResult.finalizerHistogram = new Histogram(log); logResult.criticalFinalizerHistogram = new Histogram(log); log.ReadFile(startPos, endPos, logResult); if (startMarker == null) startMarker = CommentRangeForm.startCommentString; if (endMarker == null) endMarker = CommentRangeForm.shutdownCommentString; Console.WriteLine("{0} summary for {1} Objects between {2} ({3} secs) and {4} ({5} secs)", criticalFinalizers ? "Critical Finalized" : "Finalized", logFileName, startMarker, log.TickIndexToTime(startTickIndex), endMarker, log.TickIndexToTime(endTickIndex)); } else Console.WriteLine("{0} summary for {1}", criticalFinalizers ? "Critical Finalized" : "Finalized", logFileName); // now we are ready to produce the allocation report from the allocation histogram WriteReport(criticalFinalizers ? logResult.criticalFinalizerHistogram : logResult.finalizerHistogram, ""); }
internal void LoadLogFile(string logFileName) { this.logFileName = logFileName; logFileStartOffset = 0; logFileEndOffset = long.MaxValue; log = new ReadNewLog(logFileName); lastLogResult = null; ObjectGraph.cachedGraph = null; ReadLogResult readLogResult = GetLogResult(); log.ReadFile(logFileStartOffset, logFileEndOffset, readLogResult); lastLogResult = readLogResult; viewSummaryMenuItem_Click(null, null); }
internal SummaryForm(ReadNewLog log, ReadLogResult logResult, string scenario) { // // Required for Windows Form Designer support // InitializeComponent(); this.log = log; this.logResult = logResult; this.scenario = scenario; this.Text = "Summary for " + scenario; FillInNumbers(); EnableDisableButtons(); }
/// <summary> /// Sonal: Function to generate and print Leak Report for the dump file. /// </summary> /// <param name="logFileName">dump file name</param> /// <param name="startMarker">int {0,NumHeapDumps}</param> /// <param name="endMarker">int {0,NumHeapDumps}</param> internal static void LeakReport(string logFileName, string startMarker, string endMarker) { if (startMarker == null) startMarker = "1"; if (endMarker == null) endMarker = "2"; int startIndex; int endIndex; try { startIndex = int.Parse(startMarker); endIndex = int.Parse(endMarker); } catch { throw new ArgumentException("Markers have to be positive integral values"); } startIndex--; endIndex--; if ((startIndex < 0) || (endIndex < 0)) { throw new ArgumentException("Markers can not be negative"); } ReadNewLog log = new ReadNewLog(logFileName, false); ReadLogResult entireLogResult = GetLogResult(log); log.ReadFile(0, long.MaxValue, entireLogResult, endIndex + 1); if (entireLogResult.requestedObjectGraph == null) { throw new ArgumentException("Invalid EndIndex"); } Histogram[] heapDumpHistograms = entireLogResult.heapDumpHistograms; string[] timeMarkers = new String[2]; if (startIndex < endIndex) { heapDumpHistograms = new Histogram[endIndex - startIndex + 1]; for (int i = startIndex; i <= endIndex; i++) { heapDumpHistograms[i - startIndex] = entireLogResult.heapDumpHistograms[i]; } timeMarkers = new string[endIndex - startIndex + 1]; } else { heapDumpHistograms = new Histogram[0]; timeMarkers = new string[0]; } for (int i = 0; i < timeMarkers.Length; i++) { timeMarkers[i] = string.Format("Heap dump #{0}", i + 1); } if (heapDumpHistograms.Length > 0) WriteDiffReport(heapDumpHistograms, timeMarkers, entireLogResult); else Console.WriteLine("***** No heap dumps found *****"); }
private void versionTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { if (font != MainForm.instance.font) { font = MainForm.instance.font; graphPanel.Invalidate(); typeLegendPanel.Invalidate(); } ReadLogResult lastLogResult = MainForm.instance.lastLogResult; if (lastLogResult != null && lastLogResult.sampleObjectTable != sampleObjectTable) { sampleObjectTable = lastLogResult.sampleObjectTable; lastLog = sampleObjectTable.readNewLog; typeName = lastLog.typeName; lastTickIndex = sampleObjectTable.lastTickIndex; rangeList = null; rangeCount = 0; graphPanel.Invalidate(); typeLegendPanel.Invalidate(); } }
internal Histogram(ReadNewLog readNewLog, int tickindex) { typeSizeStacktraceToCount = new int[10]; this.readNewLog = readNewLog; this.tickIndex = tickindex; }
private int WaitForProcessToConnect(string tempDir, string text, bool attachMode = false, uint result = 0) { bool fProfiledProcessInitialized = profiledProcess != null; if (fProfiledProcessInitialized) { if (!VerifyCorrectBitness(profiledProcess)) return -1; } ConnectNamedPipe(handshakingPipeHandle, IntPtr.Zero); ConnectNamedPipe(loggingPipeHandle, IntPtr.Zero); int pid = 0; byte[] handshakingBuffer = new byte[9]; int handshakingReadBytes = 0; // IMPORTANT: maxloggingBufferSize must match bufferSize defined in ProfilerCallback.cpp. const int maxloggingBufferSize = 512; byte[] loggingBuffer = new byte[maxloggingBufferSize]; int loggingReadBytes = 0; WaitingForConnectionForm waitingForConnectionForm = null; int beginTickCount = Environment.TickCount; //Do not show the text in attachmode if (attachMode == false) { if (noUI) { Console.WriteLine(text); } else { if (waitingForConnectionForm == null) waitingForConnectionForm = new WaitingForConnectionForm(); waitingForConnectionForm.setMessage(text); waitingForConnectionForm.Visible = true; } } // loop reading two pipes, // until // (1)successfully connected // (2)User canceled // (3)attach failed // (4)target process exited while (true) { #region handshaking //(1)succeeded try { handshakingReadBytes += handshakingPipe.Read(handshakingBuffer, handshakingReadBytes, 9 - handshakingReadBytes); } catch (System.IO.IOException) { } //Read 9 bytes from handshaking pipe //means the profielr was initialized successfully if (handshakingReadBytes == 9) break; Application.DoEvents(); // (2)User canceled if (!noUI) { if (waitingForConnectionForm != null && waitingForConnectionForm.DialogResult == DialogResult.Cancel) { pid = -1; break; } } #endregion handshaking #region logging // (3)attach failed // (3.1) read logging message // (3.2) break if attach failed. // (3.1) read logging message try { loggingReadBytes += loggingPipe.Read(loggingBuffer, loggingReadBytes, maxloggingBufferSize - loggingReadBytes); } catch (System.IO.IOException) { } if (loggingReadBytes == maxloggingBufferSize) { char[] charBuffer = new char[loggingReadBytes]; for (int i = 0; i < loggingReadBytes; i++) charBuffer[i] = Convert.ToChar(loggingBuffer[i]); string message = new String(charBuffer, 0, loggingReadBytes); if (attachMode == false && noUI == false) { waitingForConnectionForm.addMessage(message); } else { ShowErrorMessage(message); } loggingReadBytes = 0; while (true) { try { if (loggingPipe.Read(loggingBuffer, 0, 1) == 0) { DisconnectNamedPipe(loggingPipeHandle); ConnectNamedPipe(loggingPipeHandle, IntPtr.Zero); break; } } catch (System.IO.IOException) { DisconnectNamedPipe(loggingPipeHandle); ConnectNamedPipe(loggingPipeHandle, IntPtr.Zero); break; } } } // (3.2) break if attach failed. if (attachMode == true && result != 0) { pid = -1; break; } #endregion logging // (4)target process exited if ((fProfiledProcessInitialized && profiledProcess == null) || (profiledProcess != null && ProfiledProcessHasExited())) { pid = -1; break; } Thread.Sleep(100); } if (waitingForConnectionForm != null) waitingForConnectionForm.Visible = false; if (pid == -1) return pid; if (handshakingReadBytes == 9) { char[] charBuffer = new char[9]; for (int i = 0; i < handshakingBuffer.Length; i++) charBuffer[i] = Convert.ToChar(handshakingBuffer[i]); pid = Int32.Parse(new String(charBuffer, 0, 8), NumberStyles.HexNumber); CreateEvents(pid); string fileName = getLogFileName(pid); byte[] fileNameBuffer = new Byte[fileName.Length + 1]; for (int i = 0; i < fileName.Length; i++) fileNameBuffer[i] = (byte)fileName[i]; fileNameBuffer[fileName.Length] = 0; handshakingPipe.Write(fileNameBuffer, 0, fileNameBuffer.Length); handshakingPipe.Flush(); logFileName = tempDir + "\\" + fileName; log = new ReadNewLog(logFileName); lastLogResult = null; ObjectGraph.cachedGraph = null; while (true) { try { if (handshakingPipe.Read(handshakingBuffer, 0, 1) == 0) // && GetLastError() == 109/*ERROR_BROKEN_PIPE*/) { DisconnectNamedPipe(handshakingPipeHandle); ConnectNamedPipe(handshakingPipeHandle, IntPtr.Zero); break; } } catch (System.IO.IOException) { DisconnectNamedPipe(handshakingPipeHandle); ConnectNamedPipe(handshakingPipeHandle, IntPtr.Zero); break; } } } else { string error = string.Format("Error {0} occurred", GetLastError()); ShowErrorMessage(error); } if (noUI) { Console.WriteLine("CLRProfiler is loaded in the target process."); } else { EnableDisableViewMenuItems(); EnableDisableLaunchControls(false); if (!allocationsCheckBox.Checked && callsCheckBox.Checked) showHeapButton.Enabled = false; else showHeapButton.Enabled = true; killApplicationButton.Enabled = true; detachProcessMenuItem.Enabled = false; } logFileStartOffset = 0; logFileEndOffset = long.MaxValue; profilerConnected = true; return pid; }
private int WaitForWindowsStoreAppProcessToConnect(uint pid, string text, bool attachMode = false, uint result = 0) { if (!VerifyCorrectBitness(Process.GetProcessById((int) pid))) return -1; WaitingForConnectionForm waitingForConnectionForm = null; //Do not show the text in attachmode if (attachMode == false) { if (noUI) { Console.WriteLine(text); } else { if (waitingForConnectionForm == null) waitingForConnectionForm = new WaitingForConnectionForm(); waitingForConnectionForm.setMessage(text); waitingForConnectionForm.Visible = true; } } string fileName = getLogFileName((int)pid); string logFilePath = GetLogDir() + "\\" + fileName; // When log file has been created, that's our sign that profilerObj.dll is up and running while (!File.Exists(logFilePath)) { Application.DoEvents(); if (!noUI) { if (waitingForConnectionForm != null && waitingForConnectionForm.DialogResult == DialogResult.Cancel) { waitingForConnectionForm.Close(); return -1; } } Thread.Sleep(100); } if (waitingForConnectionForm != null) waitingForConnectionForm.Visible = false; CreateEvents((int)pid); logFileName = logFilePath; log = new ReadNewLog(logFileName); if (noUI) { Console.WriteLine("CLRProfiler is loaded in the target process."); } else { EnableDisableViewMenuItems(); EnableDisableLaunchControls(false); if (!allocationsCheckBox.Checked && callsCheckBox.Checked) showHeapButton.Enabled = false; else showHeapButton.Enabled = true; killApplicationButton.Enabled = true; } logFileStartOffset = 0; logFileEndOffset = long.MaxValue; profilerConnected = true; return (int) pid; }
private void LoadLogFile(string logFileName) { if (logFileName.EndsWith(".exe", //The string to compare to the substring at the end of this instance true, //true to ignore case during the comparison; otherwise, false. CultureInfo.InvariantCulture //An invariant culture is culture-insensitive. )) { ShowErrorMessage(logFileName +" is not a valid CLRProfiler log file name."); Environment.ExitCode = 1; exitProgram = true; return; } this.logFileName = logFileName; logFileStartOffset = 0; logFileEndOffset = long.MaxValue; processFileName = null; log = new ReadNewLog(logFileName); lastLogResult = null; ObjectGraph.cachedGraph = null; ReadLogResult readLogResult = GetLogResult(); log.ReadFile(logFileStartOffset, logFileEndOffset, readLogResult); lastLogResult = readLogResult; Text = "Analyzing " + logFileName; EnableDisableViewMenuItems(); viewSummaryMenuItem_Click(null, null); }
internal static void HeapDumpReport(string logFileName, string startMarker, string endMarker) { ReadNewLog log = new ReadNewLog(logFileName, false); ReadLogResult entireLogResult = GetLogResult(log); log.ReadFile(0, long.MaxValue, entireLogResult); Histogram[] heapDumpHistograms = entireLogResult.heapDumpHistograms; string[] timeMarkers = new String[heapDumpHistograms.Length]; if (startMarker != null || endMarker != null) { int startTickIndex = 0; int endTickIndex = entireLogResult.sampleObjectTable.lastTickIndex; if (startMarker != null) startTickIndex = FindMarkerTickIndex(startMarker, log); if (endMarker != null) endTickIndex = FindMarkerTickIndex(endMarker, log); int startIndex = 0; int endIndex = 0; for (int i = 0; i < log.heapDumpEventList.count; i++) { if (log.heapDumpEventList.eventTickIndex[i] < startTickIndex) startIndex = i + 1; if (log.heapDumpEventList.eventTickIndex[i] < endTickIndex) endIndex = i + 1; } if (endMarker == null) { Console.WriteLine("Heap dump for {0} after {1}", logFileName, startMarker); if (startIndex < log.heapDumpEventList.count) endIndex = startIndex + 1; else endIndex = startIndex; } else { Console.WriteLine("Heap dump for {0} between {1} and {2}", logFileName, startMarker, endMarker); } if (startIndex < endIndex) { heapDumpHistograms = new Histogram[endIndex - startIndex]; for (int i = startIndex; i < endIndex; i++) { heapDumpHistograms[i - startIndex] = entireLogResult.heapDumpHistograms[i]; } timeMarkers = new string[endIndex - startIndex]; } else { heapDumpHistograms = new Histogram[0]; timeMarkers = new string[0]; } } else { Console.WriteLine("Heap dumps for {0}", logFileName); } for (int i = 0; i < timeMarkers.Length; i++) { timeMarkers[i] = string.Format("Heap dump #{0}", i); } if (heapDumpHistograms.Length > 0) WriteReport(heapDumpHistograms, timeMarkers); else Console.WriteLine("***** No heap dumps found *****"); }
internal FunctionList(ReadNewLog readNewLog) { this.readNewLog = readNewLog; this.functionList = new ArrayList(); }
internal static void CommentReport(string logFileName) { // first read the entire file ReadNewLog log = new ReadNewLog(logFileName, false); ReadLogResult entireLogResult = GetLogResult(log); log.ReadFile(0, long.MaxValue, entireLogResult); Console.WriteLine("Comments logged in {0}", logFileName); Console.WriteLine("Time (seconds),Comment"); for (int i = 0; i < log.commentEventList.count; i++) Console.WriteLine("{1:f3},{0}", log.commentEventList.eventString[i], log.TickIndexToTime(log.commentEventList.eventTickIndex[i])); }
internal Histogram(ReadNewLog readNewLog) { typeSizeStacktraceToCount = new int[10]; this.readNewLog = readNewLog; }