Пример #1
0
        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;
        }
Пример #2
0
 internal void GetAllocationGraph(ReadLogResult readLogResult)
 {
     graph = readLogResult.allocatedHistogram.BuildAllocationGraph();
     PlaceVertices();
 }
Пример #3
0
        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;
        }
Пример #4
0
 private void readLogFile(ReadNewLog log, ReadLogResult logResult, string exeName, Graph.GraphType graphType)
 {
     log.ReadFile(logFileStartOffset, logFileEndOffset, logResult);
     //ViewGraph(logResult, exeName, graphType);
 }
Пример #5
0
        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;
        }
Пример #6
0
        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();
            }
        }
Пример #7
0
 internal void ReadFile(long startFileOffset, long endFileOffset, ReadLogResult readLogResult)
 {
     ReadFile(startFileOffset, endFileOffset, readLogResult, -1);
 }