Exemplo n.º 1
0
            private void ReadStack()
            {
                ExplicitStackEntry[] trueStack = null;

                if (_curThread.Depth > 0)
                {
                    // In format version 5, we began logging each thread's current call
                    // stack on the thread's first line in each block (i.e. when the
                    // StackDepth flag is set). This is the thread's true call stack at
                    // this point in the log. It reflects MethodEntry and MethodExit
                    // records that may have been lost when the log wrapped (as well
                    // as those that weren't lost).

                    trueStack = new ExplicitStackEntry[_curThread.Depth];
                    for (int i = 0; i < _curThread.Depth; ++i)
                    {
                        ExplicitStackEntry entry = new ExplicitStackEntry();
                        if (_reader.FormatVersion < 6)
                        {
                            entry.EntryLineNum = _fileReader.ReadUInt32(); // Changed from uint to ulong in version 6
                        }
                        else
                        {
                            // _reader.FormatVersion >= 6
                            entry.EntryLineNum = _fileReader.ReadUInt64(); // Changed from uint to ulong in version 6
                        }
                        entry.Level = (TracerX.TraceLevel)_fileReader.ReadByte();

                        if (Reader.Key == null)
                        {
                            entry.Logger = _reader.GetLogger(_fileReader.ReadString());
                            entry.Method = _reader.GetMethod(_fileReader.ReadString());
                        }
                        else
                        {
                            entry.Logger = _reader.GetLogger(Decrypt());
                            entry.Method = _reader.GetMethod(Decrypt());
                        }

                        entry.Depth  = (byte)(_curThread.Depth - i - 1);
                        trueStack[i] = entry;
                    }
                }

                _curThread.MakeMissingRecords(trueStack, GeneratedRecords, this);
            }
Exemplo n.º 2
0
        public Record ReadRecord()
        {
            // Read the DataFlags, then the data the Flags indicate is there.
            // Data must be read in the same order it was written (see FileLogging.WriteData).
            try {
                DataFlags flags = GetFlags();

                if (flags == DataFlags.None)
                {
                    return(null);
                }

                long startPos = _fileReader.BaseStream.Position;

                if ((flags & DataFlags.LineNumber) != DataFlags.None)
                {
                    _recordNumber = _fileReader.ReadUInt32();
                }
                else if (!InCircularPart)
                {
                    ++_recordNumber;
                }
                else
                {
                    // _recordNumber was incremented by GetFlags.
                }

                if ((flags & DataFlags.Time) != DataFlags.None)
                {
                    _time = new DateTime(_fileReader.ReadInt64());
                }

                if ((flags & DataFlags.ThreadId) != DataFlags.None)
                {
                    _threadId = _fileReader.ReadInt32();

                    // Look up or add the entry for this ThreadId.
                    if (!_foundThreadIds.TryGetValue(_threadId, out _curThread))
                    {
                        // First occurrence of this id.
                        _curThread = new ReaderThreadInfo();

                        if (!_oldThreadIds.TryGetValue(_threadId, out _curThread.Thread))
                        {
                            _curThread.Thread = new ThreadObject();
                        }

                        _curThread.Thread.Id = _threadId;
                        ThreadObject.AllThreads.Add(_curThread.Thread);
                        _foundThreadIds[_threadId] = _curThread;
                    }
                }

                if ((flags & DataFlags.ThreadName) != DataFlags.None)
                {
                    // A normal thread's name can only change from null to non-null.
                    // ThreadPool threads can alternate between null and non-null.
                    // If a thread's name changes from non-null to null, the logger
                    // writes string.Empty for the thread name.
                    string threadNameStr = _fileReader.ReadString();
                    if (threadNameStr == string.Empty)
                    {
                        _curThread.ThreadName = FindOrCreateThreadName("Thread " + _curThread.Thread.Id);
                    }
                    else
                    {
                        _curThread.ThreadName = FindOrCreateThreadName(threadNameStr);
                    }
                }
                else if (_curThread.ThreadName == null)
                {
                    _curThread.ThreadName = FindOrCreateThreadName("Thread " + _curThread.Thread.Id);
                }

                if ((flags & DataFlags.TraceLevel) != DataFlags.None)
                {
                    _curThread.Level = (TracerX.TraceLevel)_fileReader.ReadByte();
                    LevelsFound     |= _curThread.Level;
                }

                if (FormatVersion < 5)
                {
                    if ((flags & DataFlags.StackDepth) != DataFlags.None)
                    {
                        _curThread.Depth = _fileReader.ReadByte();
                    }
                    else if ((flags & DataFlags.MethodExit) != DataFlags.None)
                    {
                        --_curThread.Depth;
                    }
                }
                else
                {
                    if ((flags & DataFlags.StackDepth) != DataFlags.None)
                    {
                        _curThread.Depth = _fileReader.ReadByte();

                        if (InCircularPart)
                        {
                            if (_curThread.Depth > 0)
                            {
                                // In format version 5, we began logging each thread's current call
                                // stack on the thread's first line in each block (i.e. when the
                                // StackDepth flag is set). This is the thread's true call stack at
                                // this point in the log. It reflects MethodEntry and MethodExit
                                // records that may have been lost when the log wrapped (as well
                                // as those that weren't lost).

                                ReaderStackEntry[] trueStack = new ReaderStackEntry[_curThread.Depth];
                                for (int i = _curThread.Depth - 1; i >= 0; --i)
                                {
                                    ReaderStackEntry entry = new ReaderStackEntry();
                                    entry.EntryLineNum = _fileReader.ReadUInt32();
                                    entry.Level        = (TracerX.TraceLevel)_fileReader.ReadByte();
                                    entry.Logger       = GetLogger(_fileReader.ReadString());
                                    entry.Method       = _fileReader.ReadString();
                                    entry.Depth        = (byte)i;
                                    trueStack[i]       = entry;
                                }

                                _curThread.MakeMissingRecords(trueStack);
                            }
                            else
                            {
                                _curThread.MakeMissingRecords(null);
                            }
                        }
                    }

                    // Starting in format version 5, the viewer decrements the depth on MethodExit
                    // lines even if it was included on the line.
                    if ((flags & DataFlags.MethodExit) != DataFlags.None)
                    {
                        --_curThread.Depth;
                    }
                }

                if ((flags & DataFlags.LoggerName) != DataFlags.None)
                {
                    string loggerName = _fileReader.ReadString();
                    _curThread.Logger = GetLogger(loggerName);
                }

                if ((flags & DataFlags.MethodName) != DataFlags.None)
                {
                    _curThread.MethodName = _fileReader.ReadString();
                }

                if ((flags & DataFlags.Message) != DataFlags.None)
                {
                    _msg = _fileReader.ReadString();
                }

                // Construct the Record before incrementing depth.
                Record record = new Record(flags, _recordNumber, _time, _curThread, _msg);

                if ((flags & DataFlags.MethodEntry) != DataFlags.None)
                {
                    // Cause future records to be indented until a MethodExit is encountered.
                    ++_curThread.Depth;

                    // In format version 5+, we keep track of the call stack in the noncircular
                    // part of the log by "pushing" MethodEntry records and "popping" MethodExit records
                    if (FormatVersion >= 5 && !InCircularPart)
                    {
                        _curThread.Push(record);
                    }
                }
                else if (FormatVersion >= 5 && !InCircularPart && (flags & DataFlags.MethodExit) != DataFlags.None)
                {
                    _curThread.Pop();
                }

                BytesRead += _fileReader.BaseStream.Position - startPos;

                if (InCircularPart && _fileReader.BaseStream.Position >= MaxMb << 20)
                {
                    // We've read to the max file size in circular mode.  Wrap.
                    _fileReader.BaseStream.Position = _circularStartPos;
                }

                ++_recordsRead;
                return(record);
            } catch (Exception ex) {
                // The exception is either end-of-file or a corrupt file.
                // Either way, we're done.  Returning null tells the caller to give up.
                return(null);
            }
        }