public ReadLogResult DumpResults() { forceGcCompletedEvent.Wait(1); forceGcCompletedEvent.Reset(); long startOffset = logFileOffset(); forceGcEvent.Set(); const int maxIter = 10; // give up after ten minutes for (int iter = 0; iter < maxIter; iter++) { long lastOffset = logFileOffset(); if (forceGcCompletedEvent.Wait(60 * 1000)) { forceGcCompletedEvent.Reset(); long saveLogFileStartOffset = logFileStartOffset; logFileStartOffset = startOffset; logFileEndOffset = logFileOffset(); ReadLogResult logResult = GetLogResult(); readLogFile(log, logResult, processFileName, Graph.GraphType.HeapGraph); lastLogResult = logResult; logFileStartOffset = saveLogFileStartOffset; break; } else { // Hmm, the app didn't get back to us in 60 seconds // If the log file is growing, assume the app is still dumping // the heap, otherwise something is obviously wrong. if (logFileOffset() == lastOffset) { throw new Exception("There was no response from the application"); } } } return lastLogResult; }
internal void GetAllocationGraph(ReadLogResult readLogResult) { graph = readLogResult.allocatedHistogram.BuildAllocationGraph(); PlaceVertices(); }
private int WaitForProcessToConnect(string tempDir, string text, bool attachMode = false, uint result = 0) { bool fProfiledProcessInitialized = profiledProcess != null; 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) { breinstormin.tools.log.LogEngine.WriteLog("breinstormin.profiler", text); } else { } } // 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; #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 ex) { breinstormin.tools.log.LogEngine.WriteLog("breinstormin.profiler", ex.ToString()); } 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 { breinstormin.tools.log.LogEngine.WriteLog("breinstormin.profiler", 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 (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), System.Globalization.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()); } logFileStartOffset = 0; logFileEndOffset = long.MaxValue; profilerConnected = true; return pid; }
private void readLogFile(ReadNewLog log, ReadLogResult logResult, string exeName, Graph.GraphType graphType) { log.ReadFile(logFileStartOffset, logFileEndOffset, logResult); //ViewGraph(logResult, exeName, graphType); }
private ReadLogResult GetLogResult() { ReadLogResult readLogResult = lastLogResult; if (readLogResult == null) { 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.createdHandlesHistogram = new Histogram(log); readLogResult.destroyedHandlesHistogram = new Histogram(log); if (readLogResult.objectGraph != null) readLogResult.objectGraph.Neuter(); readLogResult.objectGraph = new ObjectGraph(log, 0); readLogResult.functionList = new FunctionList(log); readLogResult.hadCallInfo = readLogResult.hadAllocInfo = false; readLogResult.handleHash = new Dictionary<ulong, HandleInfo>(); // We may just have turned a lot of data into garbage - let's try to reclaim the memory GC.Collect(); return readLogResult; }
internal void ReadFile(long startFileOffset, long endFileOffset, ReadLogResult readLogResult, int requestedIndex) { if (stacktraceTable == null) stacktraceTable = new StacktraceTable(); if (timePos == null) timePos = new TimePos[1000]; AddTypeName(0, "Free Space"); try { System.IO.Stream s = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite); r = new System.IO.StreamReader(s); for (timePosIndex = timePosCount; timePosIndex > 0; timePosIndex--) if (timePos[timePosIndex - 1].pos <= startFileOffset) break; // start at the beginning if no later start point available or asked for info that can only // be constructed by reading the whole file. if (timePosIndex <= 1 || readLogResult.relocatedHistogram != null || readLogResult.finalizerHistogram != null || readLogResult.criticalFinalizerHistogram != null || readLogResult.liveObjectTable != null) { pos = 0; timePosIndex = 1; } else { timePosIndex--; pos = timePos[timePosIndex].pos; } if (timePosCount == 0) { timePos[0] = new TimePos(0.0, 0); timePosCount = timePosIndex = 1; } s.Position = pos; buffer = new byte[4096]; bufPos = 0; bufLevel = 0; int maxProgress = (int)(r.BaseStream.Length / 1024); line = 1; StringBuilder sb = new StringBuilder(); ulong[] ulongStack = new ulong[1000]; int[] intStack = new int[1000]; int stackPtr = 0; c = ReadChar(); bool thisIsR = false, previousWasR; bool extendedRootInfoSeen = false; int lastTickIndex = 0; bool newGcEvent = false; while (c != -1) { if (pos > endFileOffset) break; if ((line % 1024) == 0) { int currentProgress = (int)(pos / 1024); if (currentProgress <= maxProgress) { } } lastLineStartPos = pos - 1; previousWasR = thisIsR; thisIsR = false; switch (c) { case -1: break; case 'F': case 'f': { c = ReadChar(); int funcIndex = ReadInt(); while (c == ' ' || c == '\t') c = ReadChar(); string name = ReadString(sb, ' ', false, 255); while (c == ' ' || c == '\t') c = ReadChar(); string signature = ReadString(sb, '\r', true, 1023); ulong addr = ReadULong(); uint size = ReadUInt(); int modIndex = ReadInt(); int stackIndex = ReadInt(); if (c != -1) { EnsureStringCapacity(funcIndex, ref funcName); funcName[funcIndex] = name; EnsureStringCapacity(funcIndex, ref funcSignature); funcSignature[funcIndex] = signature; EnsureIntCapacity(funcIndex, ref funcModule); funcModule[funcIndex] = modIndex; string nameAndSignature = name; if (signature != null) nameAndSignature = name + ' ' + signature; if (stackIndex >= 0 && readLogResult.functionList != null) { funcSignatureIdHash[nameAndSignature] = funcIndex; readLogResult.functionList.Add(funcIndex, stackIndex, size, modIndex); } } break; } case 'T': case 't': { c = ReadChar(); int typeIndex = ReadInt(); while (c == ' ' || c == '\t') c = ReadChar(); if (c != -1 && Char.IsDigit((char)c)) { if (ReadInt() != 0) { finalizableTypes[typeIndex] = true; } } while (c == ' ' || c == '\t') c = ReadChar(); string typeName = ReadString(sb, '\r', false, 1023); if (c != -1) { AddTypeName(typeIndex, typeName); } break; } // 'A' with thread identifier case '!': { c = ReadChar(); int threadId = ReadInt(); ulong id = ReadULong(); int typeSizeStackTraceIndex = ReadInt(); typeSizeStackTraceIndex = stacktraceTable.MapTypeSizeStacktraceId(typeSizeStackTraceIndex); if (c != -1) { if (readLogResult.liveObjectTable != null) readLogResult.liveObjectTable.InsertObject(id, typeSizeStackTraceIndex, lastTickIndex, lastTickIndex, true, readLogResult.sampleObjectTable); if (pos >= startFileOffset && pos < endFileOffset && readLogResult.allocatedHistogram != null) { // readLogResult.calls.Add(new CallOrAlloc(false, threadId, typeSizeStackTraceIndex)); readLogResult.allocatedHistogram.AddObject(typeSizeStackTraceIndex, 1); } List<string> prev; if (assembliesJustLoaded.TryGetValue(threadId, out prev) && prev.Count != 0) { foreach (string assemblyName in prev) { assemblies[assemblyName] = -typeSizeStackTraceIndex; } prev.Clear(); } } readLogResult.hadAllocInfo = true; readLogResult.hadCallInfo = true; break; } case 'A': case 'a': { c = ReadChar(); ulong id = ReadULong(); int typeSizeStackTraceIndex = ReadInt(); typeSizeStackTraceIndex = stacktraceTable.MapTypeSizeStacktraceId(typeSizeStackTraceIndex); if (c != -1) { if (readLogResult.liveObjectTable != null) readLogResult.liveObjectTable.InsertObject(id, typeSizeStackTraceIndex, lastTickIndex, lastTickIndex, true, readLogResult.sampleObjectTable); if (pos >= startFileOffset && pos < endFileOffset && readLogResult.allocatedHistogram != null) { // readLogResult.calls.Add(new CallOrAlloc(false, typeSizeStackTraceIndex)); readLogResult.allocatedHistogram.AddObject(typeSizeStackTraceIndex, 1); } } readLogResult.hadAllocInfo = true; readLogResult.hadCallInfo = true; break; } case 'C': case 'c': { c = ReadChar(); if (pos < startFileOffset || pos >= endFileOffset) { while (c >= ' ') c = ReadChar(); break; } int threadIndex = ReadInt(); int stackTraceIndex = ReadInt(); stackTraceIndex = stacktraceTable.MapTypeSizeStacktraceId(stackTraceIndex); if (c != -1) { if (readLogResult.callstackHistogram != null) { readLogResult.callstackHistogram.AddObject(stackTraceIndex, 1); } List<string> prev; if (assembliesJustLoaded.TryGetValue(threadIndex, out prev) && prev.Count != 0) { foreach (string assemblyName in prev) { assemblies[assemblyName] = stackTraceIndex; } prev.Clear(); } } readLogResult.hadCallInfo = true; break; } case 'E': case 'e': { c = ReadChar(); extendedRootInfoSeen = true; thisIsR = true; if (pos < startFileOffset || pos >= endFileOffset) { while (c >= ' ') c = ReadChar(); break; } if (!previousWasR) { heapDumpEventList.AddEvent(lastTickIndex, null); if (readLogResult.objectGraph != null && !readLogResult.objectGraph.empty) { readLogResult.objectGraph.BuildTypeGraph(); readLogResult.objectGraph.Neuter(); } Histogram[] h = readLogResult.heapDumpHistograms; if (h != null) { if (h.Length == requestedIndex) readLogResult.requestedObjectGraph = readLogResult.objectGraph; readLogResult.heapDumpHistograms = new Histogram[h.Length + 1]; for (int i = 0; i < h.Length; i++) readLogResult.heapDumpHistograms[i] = h[i]; readLogResult.heapDumpHistograms[h.Length] = new Histogram(this, lastTickIndex); } readLogResult.objectGraph = new ObjectGraph(this, lastTickIndex); } ulong objectID = ReadULong(); GcRootKind rootKind = (GcRootKind)ReadInt(); GcRootFlags rootFlags = (GcRootFlags)ReadInt(); ulong rootID = ReadULong(); ObjectGraph objectGraph = readLogResult.objectGraph; if (c != -1 && objectID > 0 && objectGraph != null && (rootFlags & GcRootFlags.WeakRef) == 0) { string rootName; switch (rootKind) { case GcRootKind.Stack: rootName = "Stack"; break; case GcRootKind.Finalizer: rootName = "Finalizer"; break; case GcRootKind.Handle: rootName = "Handle"; break; default: rootName = "Other"; break; } if ((rootFlags & GcRootFlags.Pinning) != 0) rootName += ", Pinning"; if ((rootFlags & GcRootFlags.WeakRef) != 0) rootName += ", WeakRef"; if ((rootFlags & GcRootFlags.Interior) != 0) rootName += ", Interior"; if ((rootFlags & GcRootFlags.Refcounted) != 0) rootName += ", RefCounted"; int rootTypeId = objectGraph.GetOrCreateGcType(rootName); ulongStack[0] = objectID; ObjectGraph.GcObject rootObject = objectGraph.CreateObject(rootTypeId, 1, ulongStack); objectGraph.AddRootObject(rootObject, rootID); } break; } case 'R': case 'r': { c = ReadChar(); thisIsR = true; if (extendedRootInfoSeen || pos < startFileOffset || pos >= endFileOffset) { while (c >= ' ') c = ReadChar(); Histogram[] h = readLogResult.heapDumpHistograms; if (h != null) { if (h.Length == requestedIndex) readLogResult.requestedObjectGraph = readLogResult.objectGraph; } break; } if (!previousWasR) { heapDumpEventList.AddEvent(lastTickIndex, null); if (readLogResult.objectGraph != null && !readLogResult.objectGraph.empty) { readLogResult.objectGraph.BuildTypeGraph(); readLogResult.objectGraph.Neuter(); } Histogram[] h = readLogResult.heapDumpHistograms; if (h != null) { if (h.Length == requestedIndex) readLogResult.requestedObjectGraph = readLogResult.objectGraph; readLogResult.heapDumpHistograms = new Histogram[h.Length + 1]; for (int i = 0; i < h.Length; i++) readLogResult.heapDumpHistograms[i] = h[i]; readLogResult.heapDumpHistograms[h.Length] = new Histogram(this, lastTickIndex); } readLogResult.objectGraph = new ObjectGraph(this, lastTickIndex); } stackPtr = 0; ulong objectID; while ((objectID = ReadULong()) != ulong.MaxValue) { if (objectID > 0) { ulongStack[stackPtr] = objectID; stackPtr++; if (stackPtr >= ulongStack.Length) ulongStack = GrowULongVector(ulongStack); } } if (c != -1) { if (readLogResult.objectGraph != null) readLogResult.objectGraph.AddRoots(stackPtr, ulongStack); } break; } case 'O': case 'o': { c = ReadChar(); if (pos < startFileOffset || pos >= endFileOffset || readLogResult.objectGraph == null) { while (c >= ' ') c = ReadChar(); break; } ulong objectId = ReadULong(); int typeIndex = ReadInt(); uint size = ReadUInt(); stackPtr = 0; ulong objectID; while ((objectID = ReadULong()) != ulong.MaxValue) { if (objectID > 0) { ulongStack[stackPtr] = objectID; stackPtr++; if (stackPtr >= ulongStack.Length) ulongStack = GrowULongVector(ulongStack); } } if (c != -1) { ObjectGraph objectGraph = readLogResult.objectGraph; objectGraph.GetOrCreateGcType(typeIndex); int typeSizeStackTraceId = -1; int allocTickIndex = 0; // try to find the allocation stack trace and allocation time // from the live object table if (readLogResult.liveObjectTable != null) { LiveObjectTable.LiveObject liveObject; readLogResult.liveObjectTable.GetNextObject(objectId, objectId, out liveObject); if (liveObject.id == objectId) { int[] stackTrace = stacktraceTable.IndexToStacktrace(liveObject.typeSizeStacktraceIndex); int typeIndexFromLiveObject = stackTrace[0]; if (typeIndexFromLiveObject == typeIndex) { typeSizeStackTraceId = liveObject.typeSizeStacktraceIndex; allocTickIndex = liveObject.allocTickIndex; Histogram[] h = readLogResult.heapDumpHistograms; if (h != null) h[h.Length - 1].AddObject(liveObject.typeSizeStacktraceIndex, 1); } } } if (typeSizeStackTraceId == -1) typeSizeStackTraceId = stacktraceTable.GetOrCreateTypeSizeId(typeIndex, (int)size); ObjectGraph.GcObject gcObject = objectGraph.CreateAndEnterObject(objectId, typeSizeStackTraceId, stackPtr, ulongStack); gcObject.AllocTickIndex = allocTickIndex; } break; } case 'M': case 'm': { c = ReadChar(); int modIndex = ReadInt(); sb.Length = 0; while (c > '\r') { sb.Append((char)c); c = ReadChar(); } if (c != -1) { string lineString = sb.ToString(); int addrPos = lineString.LastIndexOf(" 0x"); if (addrPos <= 0) addrPos = lineString.Length; int backSlashPos = lineString.LastIndexOf(@"\"); if (backSlashPos <= 0) backSlashPos = -1; string basicName = lineString.Substring(backSlashPos + 1, addrPos - backSlashPos - 1); string fullName = lineString.Substring(0, addrPos); EnsureStringCapacity(modIndex, ref modBasicName); modBasicName[modIndex] = basicName; EnsureStringCapacity(modIndex, ref modFullName); modFullName[modIndex] = fullName; } break; } case 'U': case 'u': { c = ReadChar(); ulong oldId = ReadULong(); ulong newId = ReadULong(); uint length = ReadUInt(); Histogram reloHist = null; if (pos >= startFileOffset && pos < endFileOffset) reloHist = readLogResult.relocatedHistogram; if (readLogResult.liveObjectTable != null) readLogResult.liveObjectTable.UpdateObjects(reloHist, oldId, newId, length, lastTickIndex, readLogResult.sampleObjectTable); break; } case 'V': case 'v': { c = ReadChar(); ulong startId = ReadULong(); uint length = ReadUInt(); Histogram reloHist = null; if (pos >= startFileOffset && pos < endFileOffset) reloHist = readLogResult.relocatedHistogram; if (readLogResult.liveObjectTable != null) readLogResult.liveObjectTable.UpdateObjects(reloHist, startId, startId, length, lastTickIndex, readLogResult.sampleObjectTable); break; } case 'B': case 'b': c = ReadChar(); int startGC = ReadInt(); int induced = ReadInt(); int condemnedGeneration = ReadInt(); if (startGC != 0) newGcEvent = gcEventList.AddEvent(lastTickIndex, null); if (newGcEvent) { if (startGC != 0) { if (induced != 0) { for (int gen = 0; gen <= condemnedGeneration; gen++) inducedGcCount[gen]++; } } else { int condemnedLimit = condemnedGeneration; if (condemnedLimit == 2) condemnedLimit = 3; for (int gen = 0; gen <= condemnedLimit; gen++) { cumulativeGenerationSize[gen] += generationSize[gen]; gcCount[gen]++; } } } for (int gen = 0; gen <= 3; gen++) generationSize[gen] = 0; while (c >= ' ') { ulong rangeStart = ReadULong(); ulong rangeLength = ReadULong(); ulong rangeLengthReserved = ReadULong(); int rangeGeneration = ReadInt(); if (c == -1 || rangeGeneration < 0) break; if (readLogResult.liveObjectTable != null) { if (startGC != 0) { if (rangeGeneration > condemnedGeneration && condemnedGeneration != 2) readLogResult.liveObjectTable.Preserve(rangeStart, rangeLength, lastTickIndex); } else { readLogResult.liveObjectTable.GenerationInterval(rangeStart, rangeLength, rangeGeneration, lastTickIndex); } } generationSize[rangeGeneration] += rangeLength; } if (startGC == 0 && readLogResult.liveObjectTable != null) { readLogResult.liveObjectTable.RecordGc(lastTickIndex, condemnedGeneration, readLogResult.sampleObjectTable, false); } break; case 'L': case 'l': { c = ReadChar(); int isCritical = ReadInt(); ulong objectId = ReadULong(); if (pos >= startFileOffset && pos < endFileOffset && readLogResult.liveObjectTable != null) { // try to find the allocation stack trace and allocation time // from the live object table LiveObjectTable.LiveObject liveObject; readLogResult.liveObjectTable.GetNextObject(objectId, objectId, out liveObject); if (liveObject.id == objectId) { if (isCritical != 0 && readLogResult.criticalFinalizerHistogram != null) readLogResult.criticalFinalizerHistogram.AddObject(liveObject.typeSizeStacktraceIndex, 1); if (readLogResult.finalizerHistogram != null) readLogResult.finalizerHistogram.AddObject(liveObject.typeSizeStacktraceIndex, 1); } } break; } case 'I': case 'i': c = ReadChar(); int tickCount = ReadInt(); if (c != -1) { lastTickIndex = AddTimePos(tickCount, lastLineStartPos); if (maxTickIndex < lastTickIndex) maxTickIndex = lastTickIndex; } break; case 'G': case 'g': c = ReadChar(); int gcGen0Count = ReadInt(); int gcGen1Count = ReadInt(); int gcGen2Count = ReadInt(); // if the newer 'b' lines occur, disregard the 'g' lines. if (gcCount[0] == 0 && readLogResult.liveObjectTable != null) { if (c == -1 || gcGen0Count < 0) readLogResult.liveObjectTable.RecordGc(lastTickIndex, 0, readLogResult.sampleObjectTable, gcGen0Count < 0); else readLogResult.liveObjectTable.RecordGc(lastTickIndex, gcGen0Count, gcGen1Count, gcGen2Count, readLogResult.sampleObjectTable); } break; case 'N': case 'n': { c = ReadChar(); int funcIndex; int stackTraceIndex = ReadInt(); stackPtr = 0; int flag = ReadInt(); int matched = flag / 4; int hadTypeId = (flag & 2); bool hasTypeId = (flag & 1) == 1; if (hasTypeId) { intStack[stackPtr++] = ReadInt(); intStack[stackPtr++] = ReadInt(); } if (matched > 0 && c != -1) { /* use some other stack trace as a reference */ int otherStackTraceId = ReadInt(); otherStackTraceId = stacktraceTable.MapTypeSizeStacktraceId(otherStackTraceId); int[] stacktrace = stacktraceTable.IndexToStacktrace(otherStackTraceId); if (matched > stacktrace.Length - hadTypeId) matched = stacktrace.Length - hadTypeId; for (int i = 0; i < matched; i++) { int funcId = stacktrace[i + hadTypeId]; //Debug.Assert(funcId < funcName.Length); if (funcName[funcId] == null) funcName[funcId] = String.Empty; intStack[stackPtr++] = funcId; if (stackPtr >= intStack.Length) { intStack = GrowIntVector(intStack); } } } while ((funcIndex = ReadInt()) >= 0) { intStack[stackPtr] = funcIndex; stackPtr++; if (stackPtr >= intStack.Length) intStack = GrowIntVector(intStack); } if (c != -1) { stacktraceTable.Add(stackTraceIndex, intStack, stackPtr, hasTypeId); } break; } case 'y': case 'Y': { c = ReadChar(); int threadid = ReadInt(); if (!assembliesJustLoaded.ContainsKey(threadid)) { assembliesJustLoaded[threadid] = new List<string>(); } /* int assemblyId = */ ReadInt(); while (c == ' ' || c == '\t') { c = ReadChar(); } sb.Length = 0; while (c > '\r') { sb.Append((char)c); c = ReadChar(); } string assemblyName = sb.ToString(); assembliesJustLoaded[threadid].Add(assemblyName); break; } case 'S': case 's': { c = ReadChar(); int stackTraceIndex = ReadInt(); int funcIndex; stackPtr = 0; while ((funcIndex = ReadInt()) >= 0) { intStack[stackPtr] = funcIndex; stackPtr++; if (stackPtr >= intStack.Length) intStack = GrowIntVector(intStack); } if (c != -1) { stacktraceTable.Add(stackTraceIndex, intStack, stackPtr, false); } break; } case 'Z': case 'z': { sb.Length = 0; c = ReadChar(); while (c == ' ' || c == '\t') c = ReadChar(); while (c > '\r') { sb.Append((char)c); c = ReadChar(); } if (c != -1) { lastTickIndex = AddTimePos(lastLineStartPos); if (maxTickIndex < lastTickIndex) maxTickIndex = lastTickIndex; commentEventList.AddEvent(lastTickIndex, sb.ToString()); } break; } case 'H': case 'h': { c = ReadChar(); int threadId = ReadInt(); ulong handleId = ReadULong(); ulong initialObjectId = ReadULong(); int stacktraceId = ReadInt(); if (c != -1) { if (readLogResult.handleHash != null) readLogResult.handleHash[handleId] = new HandleInfo(threadId, handleId, initialObjectId, lastTickIndex, stacktraceId); if (readLogResult.createdHandlesHistogram != null) readLogResult.createdHandlesHistogram.AddObject(stacktraceId, 1); } break; } case 'J': case 'j': { c = ReadChar(); int threadId = ReadInt(); ulong handleId = ReadULong(); int stacktraceId = ReadInt(); if (c != -1) { if (readLogResult.handleHash != null) { if (readLogResult.handleHash.ContainsKey(handleId)) readLogResult.handleHash.Remove(handleId); else { //Console.WriteLine("Non-existent handle {0:x} destroyed in line {1}", handleId, line); //int[] stacktrace = stacktraceTable.IndexToStacktrace(stacktraceId); //for (int i = stacktrace.Length; --i >= 0; ) //{ // Console.WriteLine(" {0}", funcName[stacktrace[i]]); //} } } if (readLogResult.destroyedHandlesHistogram != null) readLogResult.destroyedHandlesHistogram.AddObject(stacktraceId, 1); } break; } default: { // just ignore the unknown while (c != '\n' && c != '\r') { c = ReadChar(); } break; } } while (c == ' ' || c == '\t') c = ReadChar(); if (c == '\r') c = ReadChar(); if (c == '\n') { c = ReadChar(); line++; } } // readLogResult.functionList.ReportCallCountSizes(readLogResult.callstackHistogram); } // catch (Exception) // { // throw new Exception(string.Format("Bad format in log file {0} line {1}", fileName, line)); // throw; // } finally { if (r != null) r.Close(); } }
internal void ReadFile(long startFileOffset, long endFileOffset, ReadLogResult readLogResult) { ReadFile(startFileOffset, endFileOffset, readLogResult, -1); }