示例#1
0
        internal void ReadEventIntoBuffer(CtfEvent evt)
        {
            if (!_readHeader)
            {
                throw new InvalidOperationException("Must read an event's header before reading an event's data.");
            }

            if (evt.IsPacked)
            {
                ReadPackedEvent();
            }
            else
            {
                ResetBuffer();

                if (evt.IsFixedSize)
                {
                    ReadBits(evt.Size);
                }
                else
                {
                    ReadStruct(evt.Fields);
                }
            }

            _readHeader = false;
        }
示例#2
0
 public void Clear()
 {
     Event       = null;
     Timestamp   = 0;
     Pid         = 0;
     Tid         = 0;
     ProcessName = null;
 }
示例#3
0
        public void AddEvent(CtfEvent evt)
        {
            while (_events.Count <= evt.ID)
            {
                _events.Add(null);
            }

            Debug.Assert(_events[evt.ID] == null);
            _events[evt.ID] = evt;
        }
示例#4
0
        public void Load(CtfMetadataParser parser)
        {
            Dictionary <string, CtfMetadataType> typeAlias = new Dictionary <string, CtfMetadataType>();
            List <CtfStream> streams = new List <CtfStream>();

            foreach (CtfMetadataDeclaration entry in parser.Parse())
            {
                switch (entry.Definition)
                {
                case CtfDeclarationTypes.Clock:
                    CtfClock clock = new CtfClock(entry.Properties);
                    _clocks[clock.Name] = clock;
                    break;

                case CtfDeclarationTypes.Trace:
                    Trace = new CtfTrace(entry.Properties);
                    break;

                case CtfDeclarationTypes.Environment:
                    Environment = new CtfEnvironment(entry.Properties);
                    break;

                case CtfDeclarationTypes.TypeAlias:
                    typeAlias[entry.Name] = entry.Type;
                    break;

                case CtfDeclarationTypes.Struct:
                    typeAlias[entry.Name] = new CtfStruct(entry.Properties, entry.Fields);
                    break;

                case CtfDeclarationTypes.Stream:
                    CtfStream stream = new CtfStream(entry.Properties);
                    while (streams.Count <= stream.ID)
                    {
                        streams.Add(null);
                    }

                    streams[stream.ID] = stream;
                    break;

                case CtfDeclarationTypes.Event:
                    CtfEvent evt = new CtfEvent(entry.Properties);
                    streams[evt.Stream].AddEvent(evt);
                    break;

                default:
                    Debug.Fail("Unknown metadata entry type.");
                    break;
                }
            }

            Streams = streams.ToArray();
            ResolveReferences(typeAlias);
        }
示例#5
0
        internal void ReadEventIntoBuffer(CtfEvent evt)
        {
            if (!_readHeader)
            {
                throw new InvalidOperationException("Must read an event's header before reading an event's data.");
            }

            if (evt.IsPacked)
            {
                ReadPackedEvent();
            }
            else
            {
                ResetBuffer();
                ReadStruct(evt.Definition);
            }

            _readHeader = false;
        }
示例#6
0
        public object[] ReadEvent(CtfEvent evt)
        {
            if (!_readHeader)
            {
                throw new InvalidOperationException("Must read an event's header before reading an event's data.");
            }

            object[] result = null;
            if (evt.IsPacked)
            {
                ReadPackedEvent();
            }
            else
            {
                ResetBuffer();
                result = ReadStruct(evt.Fields);
            }

            _readHeader = false;
            return(result);
        }
示例#7
0
        public IEnumerable <CtfEventHeader> EnumerateEventHeaders()
        {
            CtfStruct  header            = _streamDefinition.EventHeader;
            CtfEnum    id                = (CtfEnum)header.GetField("id").Type;
            CtfVariant v                 = (CtfVariant)header.GetField("v").Type;
            CtfStruct  extended          = (CtfStruct)v.GetVariant("extended").Type;
            CtfInteger extendedId        = (CtfInteger)extended.GetField("id").Type;
            CtfInteger extendedTimestamp = (CtfInteger)extended.GetField("timestamp").Type;
            CtfInteger compactTimestamp  = (CtfInteger)((CtfStruct)v.GetVariant("compact").Type).GetField("timestamp").Type;

            CtfInteger pid             = null;
            CtfInteger tid             = null;
            CtfArray   processName     = null;
            string     lastProcessName = "";
            int        processLen      = 0;
            CtfStruct  eventContext    = _streamDefinition.EventContext;

            if (eventContext != null)
            {
                pid         = (CtfInteger)eventContext.GetField("_vpid")?.Type;
                tid         = (CtfInteger)eventContext.GetField("_vtid")?.Type;
                processName = (CtfArray)eventContext.GetField("_procname")?.Type;

                // We only handle ascii process names, which seems to be the only thing lttng provides.
                if (processName != null)
                {
                    processLen = int.Parse(processName.Index);
                    Debug.Assert(processName.Type.GetSize() == 8);

                    if (processName.Type.GetSize() != 8)
                    {
                        processName = null;
                    }
                }
            }


            uint extendedIdValue = (uint)id.GetValue("extended").End;

            ulong lowMask = 0, highMask = 0, overflowBit = 0;
            ulong lastTimestamp = 0;

            while (!_eof)
            {
                if (_readHeader)
                {
                    throw new InvalidOperationException("Must read an events data before reading the header again.");
                }

                _header.Clear();
                ResetBuffer();
                ReadStruct(header);
                if (_eof)
                {
                    break;
                }

                ulong timestamp;
                uint  event_id = CtfInteger.ReadInt <uint>(id.Type, _buffer, id.BitOffset);

                if (event_id == extendedIdValue)
                {
                    event_id  = CtfInteger.ReadInt <uint>(extendedId, _buffer, extendedId.BitOffset);
                    timestamp = CtfInteger.ReadInt <ulong>(extendedTimestamp, _buffer, extendedTimestamp.BitOffset);
                }
                else
                {
                    if (overflowBit == 0)
                    {
                        overflowBit = (1ul << compactTimestamp.Size);
                        lowMask     = overflowBit - 1;
                        highMask    = ~lowMask;
                    }

                    ulong uint27timestamp = CtfInteger.ReadInt <ulong>(compactTimestamp, _buffer, compactTimestamp.BitOffset);
                    ulong prevLowerBits   = lastTimestamp & lowMask;

                    if (prevLowerBits < uint27timestamp)
                    {
                        timestamp = (lastTimestamp & highMask) | uint27timestamp;
                    }
                    else
                    {
                        timestamp  = (lastTimestamp & highMask) | uint27timestamp;
                        timestamp += overflowBit;
                    }
                }

                lastTimestamp = timestamp;

                CtfEvent evt = _streamDefinition.Events[(int)event_id];
                _header.Event     = evt;
                _header.Timestamp = timestamp;

                if (eventContext != null)
                {
                    ReadStruct(eventContext);

                    if (pid != null)
                    {
                        _header.Pid = CtfInteger.ReadInt <int>(pid, _buffer, pid.BitOffset);
                    }

                    if (tid != null)
                    {
                        _header.Tid = CtfInteger.ReadInt <int>(tid, _buffer, tid.BitOffset);
                    }

                    bool matches           = true;
                    int  processNameOffset = processName.BitOffset >> 3;

                    if (_buffer[processNameOffset] == 0)
                    {
                        lastProcessName = string.Empty;
                    }
                    else
                    {
                        int len = 0;
                        for (; len < processLen && _buffer[processNameOffset + len] != 0; len++)
                        {
                            if (len >= lastProcessName.Length)
                            {
                                matches = false;
                            }
                            else
                            {
                                matches &= lastProcessName[len] == _buffer[processNameOffset + len];
                            }
                        }

                        if (!matches || len != lastProcessName.Length)
                        {
                            lastProcessName = Encoding.UTF8.GetString(_buffer, processName.BitOffset >> 3, len);
                        }
                    }

                    _header.ProcessName = lastProcessName;
                }

                _readHeader = true;
                yield return(_header);
            }
        }
示例#8
0
        public IEnumerable <CtfEventHeader> EnumerateEventHeaders()
        {
            CtfStruct  header   = _streamDefinition.EventHeader;
            CtfVariant v        = (CtfVariant)header.GetField("v").Type;
            CtfStruct  extended = (CtfStruct)v.GetVariant("extended").Type;
            CtfStruct  compact  = (CtfStruct)v.GetVariant("compact").Type;

            ulong lowMask = 0, highMask = 0, overflowBit = 0;
            ulong lastTimestamp = 0;

            StringBuilder processName = new StringBuilder();

            while (!_eof)
            {
                if (_readHeader)
                {
                    throw new InvalidOperationException("Must read an events data before reading the header again.");
                }

                _header.Clear();
                ResetBuffer();

                object[] result = ReadStruct(header);
                if (_eof)
                {
                    break;
                }

                ulong   timestamp;
                CtfEnum en       = (CtfEnum)header.GetField("id").Type;
                uint    event_id = header.GetFieldValue <uint>(result, "id");

                result = header.GetFieldValue <object[]>(result, "v");
                if (en.GetName((int)event_id) == "extended")
                {
                    event_id  = extended.GetFieldValue <uint>(result, "id");
                    timestamp = extended.GetFieldValue <ulong>(result, "timestamp");
                }
                else
                {
                    if (overflowBit == 0)
                    {
                        CtfInteger compactTimestamp = (CtfInteger)compact.GetField("timestamp").Type;
                        overflowBit = (1ul << compactTimestamp.Size);
                        lowMask     = overflowBit - 1;
                        highMask    = ~lowMask;
                    }

                    ulong uint27timestamp = compact.GetFieldValue <ulong>(result, "timestamp");
                    ulong prevLowerBits   = lastTimestamp & lowMask;

                    if (prevLowerBits < uint27timestamp)
                    {
                        timestamp = (lastTimestamp & highMask) | uint27timestamp;
                    }
                    else
                    {
                        timestamp  = (lastTimestamp & highMask) | uint27timestamp;
                        timestamp += overflowBit;
                    }
                }

                lastTimestamp = timestamp;

                CtfEvent evt = _streamDefinition.Events[(int)event_id];
                _header.Event     = evt;
                _header.Timestamp = timestamp;

                CtfStruct eventContext = _streamDefinition.EventContext;
                if (eventContext != null)
                {
                    result      = ReadStruct(eventContext);
                    _header.Pid = eventContext.GetFieldValue <int>(result, "_vpid");
                    _header.Tid = eventContext.GetFieldValue <int>(result, "_vtid");

                    int      procnameIndex = eventContext.GetFieldIndex("_procname");
                    object[] procname      = (object[])(result[procnameIndex]);
                    processName.Clear();
                    for (int i = 0; i < 17; i++)
                    {
                        sbyte b = (sbyte)procname[i];
                        if (b == 0)
                        {
                            break;
                        }

                        processName.Append((char)b);
                    }

                    _header.ProcessName = processName.ToString();
                }

                _readHeader = true;
                yield return(_header);
            }
        }