예제 #1
0
            private void ReadThreadID()
            {
                _threadId = _fileReader.ReadInt32() + _reader._maxThreadIDFromPrevSession;
                if (_threadId > MaxThreadID)
                {
                    MaxThreadID = _threadId;
                }

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

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

                    _curThread.Thread.Id = _threadId;

                    lock (ThreadObjects.Lock)
                    {
                        ThreadObjects.AllThreadObjects.Add(_curThread.Thread);
                    }

                    _reader._foundThreadIds[_threadId] = _curThread;
                }
            }
예제 #2
0
        public Record(DataFlags dataflags, ulong msgNum, DateTime time, ReaderThreadInfo threadInfo, Reader.Session session, string msg)
        {
            MsgNum     = msgNum;
            Time       = time;
            Thread     = threadInfo.Thread;
            ThreadName = threadInfo.ThreadName;
            Level      = threadInfo.Level;
            Logger     = threadInfo.Logger;
            StackDepth = threadInfo.Depth;
            MethodName = threadInfo.MethodName;
            Caller     = threadInfo.StackTop;
            Session    = session;

            if ((dataflags & DataFlags.MethodEntry) != DataFlags.None)
            {
                // This is a method entry record.  It always contains exactly one line of text.
                IsEntry = true;
                Lines   = new string[] { string.Format("{{{0}: entered", MethodName.Name) };
            }
            else if ((dataflags & DataFlags.MethodExit) != DataFlags.None)
            {
                // Method exit records always contain exactly one line of text.
                IsExit = true;
                Lines  = new string[] { string.Format("}}{0}: exiting", MethodName.Name) };
            }
            else
            {
                // The message text for this record may contain newlines.  Split the
                // message into one or more lines.
                Lines = msg.Split(_splitArg);

                if (Lines.Length > 1)
                {
                    // It's common for a carriage return to exist at the
                    // end of each line.  Remove them.
                    for (int i = 0; i < Lines.Length; ++i)
                    {
                        Lines[i] = Lines[i].TrimEnd('\r');
                    }

                    // It's common for the last line to be empty.  If so, remove it.
                    if (Lines.Last().Trim() == string.Empty)
                    {
                        Lines = Lines.Take(Lines.Length - 1).ToArray();
                    }
                }

                IsCollapsed = Lines.Length > 1 && !Settings.Default.ExpandNewlines;
            }

            // Each line also has a bool to indicate if it is bookmarked
            // and a row index it may map to.
            IsBookmarked = new bool[Lines.Length];
            RowIndices   = new int[Lines.Length];
        }
예제 #3
0
파일: Reader.cs 프로젝트: NathDevAU/TracerX
 public void CloseLogFile()
 {
     _fileReader.Close();
     _fileReader       = null;
     _curThread        = null;
     _foundThreadIds   = null;
     _foundThreadNames = null;
     _oldThreadNames   = null;
     _oldThreadIds     = null;
     _foundLoggers     = null;
     _oldLoggers       = null;
 }
예제 #4
0
파일: Record.cs 프로젝트: NathDevAU/TracerX
        // This constructs a missing MethodEntry Record from the given ReaderStackEntry.
        public Record(ReaderThreadInfo threadInfo, ReaderStackEntry methodEntry)
        {
            IsEntry    = true;
            MsgNum     = 0;                 // TBD
            Time       = DateTime.MinValue; // TBD
            Index      = 0;                 // TBD
            Thread     = threadInfo.Thread;
            ThreadName = threadInfo.ThreadName;
            Level      = methodEntry.Level;
            Logger     = methodEntry.Logger;
            StackDepth = methodEntry.Depth;
            MethodName = methodEntry.Method;
            Lines      = new string[] { string.Format("{{{0}: entered (replaces record lost due to wrapping)", MethodName) };

            // Each record also has a bool to indicate if it is bookmarked
            // and a row index it may map to.
            IsBookmarked = new bool[1];
            RowIndices   = new int[1];
        }
예제 #5
0
파일: Reader.cs 프로젝트: NathDevAU/TracerX
        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);
            }
        }