/// <summary>
        /// Given a stream that contains PerfInfo commands, parses the stream and stores data in the given dictionary.
        /// Key: somedll.ni.dll		Value: {some guid}
        /// </summary>
        public void ParsePerfInfoFile(Stream stream, Dictionary <string, string> guids)
        {
            FastStream source = new FastStream(stream);

            source.MoveNext();
            source.SkipWhiteSpace();

            StringBuilder sb = new StringBuilder();

            while (!source.EndOfStream)
            {
                source.ReadAsciiStringUpTo(';', sb);
                source.MoveNext();
                string command = sb.ToString();
                sb.Clear();

                if (command == "ImageLoad")                 // TODO: should be a constant maybe?
                {
                    source.ReadAsciiStringUpTo(';', sb);
                    string path = sb.ToString();
                    sb.Clear();
                    source.MoveNext();

                    source.ReadAsciiStringUpTo(';', sb);
                    string guid = sb.ToString().TrimEnd();
                    sb.Clear();

                    guids[GetFileName(path)] = guid;
                }

                source.SkipUpTo('\n');
                source.MoveNext();
            }
        }
        private StackFrame ReadFrame(FastStream source)
        {
            StringBuilder sb = new StringBuilder();

            // Address
            source.SkipWhiteSpace();
            source.ReadAsciiStringUpTo(' ', sb);
            string address = sb.ToString();

            sb.Clear();

            // Trying to get the module and symbol...
            source.SkipWhiteSpace();

            source.ReadAsciiStringUpToLastBeforeTrue('(', sb, delegate(byte c)
            {
                if (c != '\n' && !source.EndOfStream)
                {
                    return(true);
                }

                return(false);
            });
            string assumedSymbol = sb.ToString();

            sb.Clear();

            source.ReadAsciiStringUpTo('\n', sb);

            string assumedModule = sb.ToString();

            sb.Clear();

            assumedModule = RemoveOuterBrackets(assumedModule.Trim());

            string actualModule = assumedModule;
            string actualSymbol = RemoveOuterBrackets(assumedSymbol.Trim());

            if (assumedModule.EndsWith(".map"))
            {
                string[] moduleSymbol = GetSymbolFromMicrosoftMap(assumedSymbol, assumedModule);
                actualSymbol = string.IsNullOrEmpty(moduleSymbol[1]) ? assumedModule : moduleSymbol[1];
                actualModule = moduleSymbol[0];
            }

            // Can't use Path.GetFileName Because it throws on illegal Windows characters
            actualModule = GetFileName(actualModule);
            actualSymbol = RemoveOffset(actualSymbol.Trim());

            return(new StackFrame(address, actualModule, actualSymbol));
        }
        private ScheduleSwitch ReadScheduleSwitch(FastStream source)
        {
            StringBuilder sb = new StringBuilder();

            source.SkipUpTo('=');
            source.MoveNext();

            source.ReadAsciiStringUpTo(' ', sb);
            string prevComm = sb.ToString();

            sb.Clear();

            source.SkipUpTo('=');
            source.MoveNext();

            int prevTid = source.ReadInt();

            source.SkipUpTo('=');
            source.MoveNext();

            int prevPrio = source.ReadInt();

            source.SkipUpTo('=');
            source.MoveNext();

            char prevState = (char)source.Current;

            source.MoveNext();
            source.SkipUpTo('n');             // this is to bypass the ==>
            source.SkipUpTo('=');
            source.MoveNext();

            source.ReadAsciiStringUpTo(' ', sb);
            string nextComm = sb.ToString();

            sb.Clear();

            source.SkipUpTo('=');
            source.MoveNext();

            int nextTid = source.ReadInt();

            source.SkipUpTo('=');
            source.MoveNext();

            int nextPrio = source.ReadInt();

            return(new ScheduleSwitch(prevComm, prevTid, prevPrio, prevState, nextComm, nextTid, nextPrio));
        }
        /// <summary>
        /// Given a stream that contains PerfInfo commands, parses the stream and stores data in the given dictionary.
        /// Key: somedll.ni.dll		Value: {some guid}
        /// </summary>
        public void ParsePerfInfoFile(Stream stream, Dictionary <string, string> guids, Dictionary <string, ulong> baseAddresses)
        {
            FastStream source = new FastStream(stream);

            source.MoveNext();
            source.SkipWhiteSpace();

            StringBuilder sb = new StringBuilder();

            while (!source.EndOfStream)
            {
                source.ReadAsciiStringUpTo(';', sb);
                source.MoveNext();
                string command = sb.ToString();
                sb.Clear();

                if (command == "ImageLoad") // TODO: should be a constant maybe?
                {
                    source.ReadAsciiStringUpTo(';', sb);
                    string path = sb.ToString();
                    sb.Clear();
                    source.MoveNext();

                    source.ReadAsciiStringUpTo(';', sb);
                    string guid = sb.ToString().TrimEnd();
                    sb.Clear();
                    source.MoveNext();

                    guids[GetFileName(path)] = guid;

                    // Check to see if the base address has been appended to the line.
                    if (source.Current != '\n')
                    {
                        sb.Clear();
                        source.ReadAsciiStringUpTo(';', sb);
                        string strBaseAddr = sb.ToString().TrimEnd();
                        if (!string.IsNullOrEmpty(strBaseAddr))
                        {
                            ulong baseAddr = ulong.Parse(strBaseAddr, System.Globalization.NumberStyles.HexNumber);
                            baseAddresses[GetFileName(path)] = baseAddr;
                        }
                    }
                }

                source.SkipUpTo('\n');
                source.MoveNext();
            }
        }
        /// <summary>
        /// Given a stream with the symbols, this function parses the stream and stores the contents in the given mapper
        /// </summary>
        public void ParseSymbolFile(Stream stream, Mapper mapper)
        {
            FastStream source = new FastStream(stream);

            source.MoveNext();             // Prime Current.
            this.SkipPreamble(source);     // Remove encoding stuff if it's there
            source.SkipWhiteSpace();

            StringBuilder sb = new StringBuilder();

            Func <byte, bool> untilWhiteSpace = (byte c) => { return(!char.IsWhiteSpace((char)c)); };

            while (!source.EndOfStream)
            {
                source.ReadAsciiStringUpToTrue(sb, untilWhiteSpace);
                ulong start = ulong.Parse(sb.ToString(), System.Globalization.NumberStyles.HexNumber);
                sb.Clear();
                source.SkipWhiteSpace();

                source.ReadAsciiStringUpToTrue(sb, untilWhiteSpace);
                ulong size = ulong.Parse(sb.ToString(), System.Globalization.NumberStyles.HexNumber);
                sb.Clear();
                source.SkipWhiteSpace();

                source.ReadAsciiStringUpTo('\n', sb);
                string symbol = sb.ToString().TrimEnd();
                sb.Clear();

                mapper.Add(start, size, symbol);

                source.SkipWhiteSpace();
            }
        }
Exemplo n.º 6
0
        public void BasicReadLine()
        {
            FastStream stream = this.GetTestStream();

            SkipBOM(stream);
            StringBuilder sb = new StringBuilder();

            stream.ReadAsciiStringUpTo('\n', sb);
            Assert.Equal("12345\r", sb.ToString());
        }
Exemplo n.º 7
0
        public void LongRestoreAndMovePastHistory()
        {
            FastStream stream = this.GetTestStream();

            SkipBOM(stream);
            var mp = stream.MarkPosition();

            stream.SkipUpTo('a');
            stream.RestoreToMark(mp);
            StringBuilder sb = new StringBuilder();

            stream.ReadAsciiStringUpTo('b', sb);
            Assert.Equal("12345\r\n6789a\r\n", sb.ToString());
        }
Exemplo n.º 8
0
        private ThreadExit ReadExit(FastStream source)
        {
            StringBuilder sb = new StringBuilder();

            source.SkipUpTo('=');
            source.MoveNext();

            source.ReadAsciiStringUpTo(' ', sb);
            string comm = sb.ToString();

            sb.Clear();

            source.SkipUpTo('=');
            source.MoveNext();

            int tid = source.ReadInt();

            source.SkipUpTo('=');
            source.MoveNext();

            int prio = source.ReadInt();

            return(new ThreadExit(comm, tid, prio));
        }
        private IEnumerable <LinuxEvent> NextEvent(Regex regex, FastStream source)
        {
            string line = string.Empty;

            while (true)
            {
                source.SkipWhiteSpace();

                if (source.EndOfStream)
                {
                    break;
                }

                EventKind eventKind = EventKind.Cpu;

                StringBuilder sb = new StringBuilder();

                // Command - Stops at first number AFTER whitespace
                while (!this.IsNumberChar((char)source.Current))
                {
                    sb.Append(' ');
                    source.ReadAsciiStringUpToTrue(sb, delegate(byte c)
                    {
                        return(!char.IsWhiteSpace((char)c));
                    });
                    source.SkipWhiteSpace();
                }

                string comm = sb.ToString().Trim();
                sb.Clear();

                // Process ID
                int pid = source.ReadInt();
                source.MoveNext();                 // Move past the "/"

                // Thread ID
                int tid = source.ReadInt();

                // CPU
                source.SkipWhiteSpace();
                source.MoveNext();                 // Move past the "["
                int cpu = source.ReadInt();
                source.MoveNext();                 // Move past the "]"

                // Time
                source.SkipWhiteSpace();
                source.ReadAsciiStringUpTo(':', sb);

                double time = double.Parse(sb.ToString()) * 1000; // To convert to MSec
                sb.Clear();
                source.MoveNext();                                // Move past ":"

                // Time Property
                source.SkipWhiteSpace();
                int timeProp = -1;
                if (this.IsNumberChar((char)source.Current))
                {
                    timeProp = source.ReadInt();
                }

                // Event Name
                source.SkipWhiteSpace();
                source.ReadAsciiStringUpTo(':', sb);
                string eventName = sb.ToString();
                sb.Clear();
                source.MoveNext();

                // Event Properties
                // I mark a position here because I need to check what type of event this is without screwing up the stream
                var markedPosition = source.MarkPosition();
                source.ReadAsciiStringUpTo('\n', sb);
                string eventDetails = sb.ToString().Trim();
                sb.Clear();

                if (eventDetails.Length >= SchedulerEvent.Name.Length && eventDetails.Substring(0, SchedulerEvent.Name.Length) == SchedulerEvent.Name)
                {
                    eventKind = EventKind.Scheduler;
                }

                // Now that we know the header of the trace, we can decide whether or not to skip it given our pattern
                if (regex != null && !regex.IsMatch(eventName))
                {
                    while (true)
                    {
                        source.MoveNext();
                        if (this.IsEndOfSample(source, source.Current, source.Peek(1)))
                        {
                            break;
                        }
                    }

                    yield return(null);
                }
                else
                {
                    LinuxEvent linuxEvent;

                    Frame threadTimeFrame = null;

                    // For the sake of immutability, I have to do a similar if-statement twice. I'm trying to figure out a better way
                    //   but for now this will do.
                    ScheduleSwitch schedSwitch = null;
                    if (eventKind == EventKind.Scheduler)
                    {
                        source.RestoreToMark(markedPosition);
                        schedSwitch = this.ReadScheduleSwitch(source);
                        source.SkipUpTo('\n');
                    }

                    IEnumerable <Frame> frames = this.ReadFramesForSample(comm, pid, tid, threadTimeFrame, source);

                    if (eventKind == EventKind.Scheduler)
                    {
                        linuxEvent = new SchedulerEvent(comm, tid, pid, time, timeProp, cpu, eventName, eventDetails, frames, schedSwitch);
                    }
                    else
                    {
                        linuxEvent = new CpuEvent(comm, tid, pid, time, timeProp, cpu, eventName, eventDetails, frames);
                    }

                    yield return(linuxEvent);
                }
            }
        }
Exemplo n.º 10
0
        private ScheduleSwitch ReadScheduleSwitch(FastStream source)
        {
            StringBuilder sb = new StringBuilder();

            // There are two formats for ScheduleSwitch serialization:
            // Example1: sched:sched_switch: prev_comm=swapper/3 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=rcu_sched next_pid=8 next_prio=120
            // Example2: sched:sched_switch: perf_4.9:3005 [49] S ==> swapper/2:0 [120]

            // Skip "sched:sched_switch: "
            source.SkipUpTo(' ');
            source.SkipSpace();

            // Figure out which format we have.
            var pos = source.MarkPosition();

            // Look for 'prev_comm' (Example1)
            source.ReadFixedString(9, sb);
            string nextField = sb.ToString();

            sb.Clear();

            if (nextField.Equals("prev_comm"))
            {
                // This is of the format in Example1.

                source.SkipUpTo('=');
                source.MoveNext();

                source.ReadAsciiStringUpTo(' ', sb);
                string prevComm = sb.ToString();
                sb.Clear();

                source.SkipUpTo('=');
                source.MoveNext();

                int prevTid = source.ReadInt();

                source.SkipUpTo('=');
                source.MoveNext();

                int prevPrio = source.ReadInt();

                source.SkipUpTo('=');
                source.MoveNext();

                char prevState = (char)source.Current;

                source.MoveNext();
                source.SkipUpTo('n'); // this is to bypass the ==>
                source.SkipUpTo('=');
                source.MoveNext();

                source.ReadAsciiStringUpTo(' ', sb);
                string nextComm = sb.ToString();
                sb.Clear();

                source.SkipUpTo('=');
                source.MoveNext();

                int nextTid = source.ReadInt();

                source.SkipUpTo('=');
                source.MoveNext();

                int nextPrio = source.ReadInt();

                return(new ScheduleSwitch(prevComm, prevTid, prevPrio, prevState, nextComm, nextTid, nextPrio));
            }
            else
            {
                // This is of the format in Example2.

                // Restore the position back so the full text can be parsed here.
                source.RestoreToMark(pos);

                source.ReadAsciiStringUpTo(':', sb);
                string prevComm = sb.ToString();
                sb.Clear();

                source.MoveNext();

                int prevTid = source.ReadInt();

                source.SkipUpTo('[');
                source.MoveNext();

                int prevPrio = source.ReadInt();

                source.MoveNext();
                source.SkipWhiteSpace();

                char prevState = (char)source.Current;

                source.SkipUpTo('>'); // this is to bypass the ==>
                source.MoveNext();
                source.SkipWhiteSpace();

                source.ReadAsciiStringUpTo(':', sb);
                string nextComm = sb.ToString();
                sb.Clear();

                source.MoveNext();

                int nextTid = source.ReadInt();

                source.SkipUpTo('[');
                source.MoveNext();

                int nextPrio = source.ReadInt();

                return(new ScheduleSwitch(prevComm, prevTid, prevPrio, prevState, nextComm, nextTid, nextPrio));
            }
        }
Exemplo n.º 11
0
        private IEnumerable <LinuxEvent> NextEvent(Regex regex, FastStream source)
        {
            string line = string.Empty;

            while (true)
            {
                source.SkipWhiteSpace();

                if (source.EndOfStream)
                {
                    break;
                }

                EventKind eventKind = EventKind.Cpu;

                StringBuilder sb = new StringBuilder();

                // Fetch Command (processName) - Stops when it sees the pattern \s+\d+/\d
                int idx = FindEndOfProcessCommand(source);
                if (idx < 0)
                {
                    break;
                }

                source.ReadFixedString(idx, sb);
                source.SkipWhiteSpace();
                string processCommand = sb.ToString();
                sb.Clear();

                // Process ID
                int pid = source.ReadInt();

                // Detect whether or not the Thread ID is present.
                int tid = pid;
                if (source.Peek(0) == '/')
                {
                    // Thread ID
                    source.MoveNext(); // Move past the "/"
                    tid = source.ReadInt();
                }

                // CPU
                source.SkipWhiteSpace();
                int cpu = -1;
                if (source.Peek(0) == '[')
                {
                    source.MoveNext(); // Move past the "["
                    cpu = source.ReadInt();
                    source.MoveNext(); // Move past the "]"
                }

                // Time
                source.SkipWhiteSpace();
                source.ReadAsciiStringUpTo(':', sb);

                double time = double.Parse(sb.ToString(), CultureInfo.InvariantCulture) * 1000; // To convert to MSec
                sb.Clear();
                source.MoveNext();                                                              // Move past ":"

                // Time Property
                source.SkipWhiteSpace();
                int timeProp = -1;
                if (IsNumberChar((char)source.Current))
                {
                    timeProp = source.ReadInt();
                }

                // Event Name
                source.SkipWhiteSpace();
                source.ReadAsciiStringUpTo(':', sb);
                string eventName = sb.ToString();
                sb.Clear();
                source.MoveNext();

                // Event Properties
                // I mark a position here because I need to check what type of event this is without screwing up the stream
                var markedPosition = source.MarkPosition();
                source.ReadAsciiStringUpTo('\n', sb);
                string eventDetails = sb.ToString().Trim();
                sb.Clear();

                if (eventDetails.Length >= SchedulerEvent.Name.Length && eventDetails.Substring(0, SchedulerEvent.Name.Length) == SchedulerEvent.Name)
                {
                    eventKind = EventKind.Scheduler;
                }
                else if (eventDetails.Length > ThreadExitEvent.Name.Length && eventDetails.Substring(0, ThreadExitEvent.Name.Length) == ThreadExitEvent.Name)
                {
                    eventKind = EventKind.ThreadExit;
                }

                // Now that we know the header of the trace, we can decide whether or not to skip it given our pattern
                if (regex != null && !regex.IsMatch(eventName))
                {
                    while (true)
                    {
                        source.MoveNext();
                        if (IsEndOfSample(source, source.Current, source.Peek(1)))
                        {
                            break;
                        }
                    }

                    yield return(null);
                }
                else
                {
                    LinuxEvent linuxEvent;

                    Frame threadTimeFrame = null;

                    // For the sake of immutability, I have to do a similar if-statement twice. I'm trying to figure out a better way
                    //   but for now this will do.
                    ScheduleSwitch schedSwitch = null;
                    if (eventKind == EventKind.Scheduler)
                    {
                        source.RestoreToMark(markedPosition);
                        schedSwitch = ReadScheduleSwitch(source);
                        source.SkipUpTo('\n');
                    }

                    ThreadExit exit = null;
                    if (eventKind == EventKind.ThreadExit)
                    {
                        source.RestoreToMark(markedPosition);
                        exit = ReadExit(source);
                        source.SkipUpTo('\n');
                    }

                    IEnumerable <Frame> frames = ReadFramesForSample(processCommand, pid, tid, threadTimeFrame, source);

                    if (eventKind == EventKind.Scheduler)
                    {
                        linuxEvent = new SchedulerEvent(processCommand, tid, pid, time, timeProp, cpu, eventName, eventDetails, frames, schedSwitch);
                    }
                    else if (eventKind == EventKind.ThreadExit)
                    {
                        linuxEvent = new ThreadExitEvent(processCommand, tid, pid, time, timeProp, cpu, eventName, eventDetails, frames, exit);
                    }
                    else
                    {
                        linuxEvent = new CpuEvent(processCommand, tid, pid, time, timeProp, cpu, eventName, eventDetails, frames);
                    }

                    yield return(linuxEvent);
                }
            }
        }