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; }
public void Clear() { Event = null; Timestamp = 0; Pid = 0; Tid = 0; ProcessName = null; }
public void AddEvent(CtfEvent evt) { while (_events.Count <= evt.ID) { _events.Add(null); } Debug.Assert(_events[evt.ID] == null); _events[evt.ID] = evt; }
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); }
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; }
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); }
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); } }
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); } }