unsafe protected override DynamicTraceEventData TryLookup(TraceEvent unknownEvent) { // WPP is always classic if (unknownEvent.ClassicProvider) { var taskGuid = unknownEvent.taskGuid; var tmfPath = GetTmfPathForTaskGuid(taskGuid); if (tmfPath != null) { var templates = CreateTemplatesForTMFFile(taskGuid, tmfPath); // Register all the templates in the file, and if we found the specific one we are looking for return that one. DynamicTraceEventData ret = null; foreach (var template in templates) { if (template.eventID == unknownEvent.eventID) { ret = template; } else { RegisterTemplate(template); } } // If we fail, remove the file so we don't continually try to parse the file. if (ret == null) { m_tmfDataFilePathsByFileNameBase[taskGuid.ToString()] = null; } return(ret); } } return(null); }
/// <summary> /// Give meta-data for an event, passed as a EventPipeEventMetaDataHeader and readerForParameters /// which is a StreamReader that points at serialized parameter information, decode the meta-data /// and record a template associated with this source. The readerForParameters is advanced beyond /// the event parameters information. /// </summary> internal void OnNewEventPipeEventDefinition(EventPipeEventMetaDataHeader eventMetaDataHeader, PinnedStreamReader readerForParameters) { // Convert the EventPipe data into a DynamicTraceEventData, which is how TraceEvent does dynamic event parsing. DynamicTraceEventData template = ReadEventParametersAndBuildTemplate(eventMetaDataHeader, readerForParameters); _metadataTemplates[template] = template; }
internal override unsafe DynamicTraceEventData TryLookup(TraceEvent unknownEvent) { // WPP is always classic if (unknownEvent.IsClassicProvider) { var taskGuid = unknownEvent.taskGuid; var tmfPath = GetTmfPathForTaskGuid(taskGuid); if (tmfPath != null) { var templates = CreateTemplatesForTMFFile(taskGuid, tmfPath); // Register all the templates in the file, and if we found the specific one we are looking for return that one. DynamicTraceEventData ret = null; foreach (var template in templates) { if (template.eventID == unknownEvent.eventID) { ret = template; } else { OnNewEventDefintion(template, false); } } // If we fail, remove the file so we don't ever try to this Task's events again. m_tmfDataFilePathsByFileNameBase[taskGuid.ToString()] = null; return(ret); } } return(null); }
/// <summary> /// Give meta-data for an event, passed as a EventPipeEventMetaDataHeader and readerForParameters /// which is a StreamReader that points at serialized parameter information, decode the meta-data /// and register the meta-data with the TraceEventParser infrastruture. The readerForParameters /// is advanced beyond the event parameters information. /// </summary> internal void OnNewEventPipeEventDefinition(EventPipeEventMetaDataHeader eventMetaDataHeader, PinnedStreamReader readerForParameters) { // Convert the EventPipe data into a DynamicTraceEventData, which is how TraceEvent does dynamic event parsing. DynamicTraceEventData template = ReadEventParametersAndBuildTemplate(eventMetaDataHeader, readerForParameters); OnNewEventDefintion(template, mayHaveExistedBefore: true); }
private static void ComputeFieldInfo(DynamicTraceEventData template, XmlReader reader) { List <string> payloadNames = new List <string>(); List <DynamicTraceEventData.PayloadFetch> payloadFetches = new List <DynamicTraceEventData.PayloadFetch>(); int offset = 0; while (reader.Read()) { if (reader.Name == "data") { Type type = GetTypeForManifestTypeName(reader.GetAttribute("inType")); payloadNames.Add(reader.GetAttribute("name")); payloadFetches.Add(new DynamicTraceEventData.PayloadFetch(offset, type)); if (offset >= 0) { int size = DynamicTraceEventData.SizeOfType(type); Debug.Assert(size != 0); if (size >= 0) { offset += size; } else { offset = int.MinValue; } } } } template.payloadNames = payloadNames.ToArray(); template.payloadFetches = payloadFetches.ToArray(); }
/// <summary> /// Register 'template so that it is known to this TraceEventParser. /// </summary> protected void RegisterTemplate(DynamicTraceEventData template) { this.source.RegisterEventTemplate(template); if (m_allCallbackCalled) template.Action += m_allCallback; m_state.m_templates.Add(template); }
internal override DynamicTraceEventData TryLookup(TraceEvent unknownEvent) { if (unknownEvent.IsClassicProvider) { return(null); } EventPipeEventSource eventPipeSource = source as EventPipeEventSource; DynamicTraceEventData template = null; if (eventPipeSource != null) { eventPipeSource.TryGetTemplateFromMetadata(unknownEvent, out template); } return(template); }
/// <summary> /// Given the EventPipe metaData header and a stream pointing at the serialized meta-data for the parameters for the /// event, create a new DynamicTraceEventData that knows how to parse that event. /// ReaderForParameters.Current is advanced past the parameter information. /// </summary> private DynamicTraceEventData ReadEventParametersAndBuildTemplate(EventPipeEventMetaDataHeader eventMetaDataHeader, PinnedStreamReader readerForParameters) { int opcode; string opcodeName; GetOpcodeFromEventName(eventMetaDataHeader.EventName, out opcode, out opcodeName); DynamicTraceEventData.PayloadFetchClassInfo classInfo = null; DynamicTraceEventData template = new DynamicTraceEventData(null, eventMetaDataHeader.EventId, 0, eventMetaDataHeader.EventName, Guid.Empty, opcode, opcodeName, eventMetaDataHeader.ProviderId, eventMetaDataHeader.ProviderName); // If the metadata contains no parameter metadata, don't attempt to read it. if (!eventMetaDataHeader.ContainsParameterMetadata) { template.payloadNames = new string[0]; template.payloadFetches = new DynamicTraceEventData.PayloadFetch[0]; return(template); } // Read the count of event payload fields. int fieldCount = readerForParameters.ReadInt32(); Debug.Assert(0 <= fieldCount && fieldCount < 0x4000); if (fieldCount > 0) { // Recursively parse the metadata, building up a list of payload names and payload field fetch objects. classInfo = ParseFields(readerForParameters, fieldCount); } else { classInfo = new DynamicTraceEventData.PayloadFetchClassInfo() { FieldNames = new string[0], FieldFetches = new DynamicTraceEventData.PayloadFetch[0] }; } template.payloadNames = classInfo.FieldNames; template.payloadFetches = classInfo.FieldFetches; return(template); }
private List <DynamicTraceEventData> CreateTemplatesForTMFFile(Guid taskGuid, string tmfPath) { List <DynamicTraceEventData> templates = new List <DynamicTraceEventData>(); List <Type> parameterTypes = new List <Type>(); using (StreamReader tmfData = File.OpenText(tmfPath)) { string taskName = null; string providerName = null; Guid providerGuid = Guid.Empty; Match m; for (; ;) { var line = tmfData.ReadLine(); if (line == null) { break; } if (providerGuid == Guid.Empty) { m = Regex.Match(line, @"PDB: .*?(\w+)\.pdb\s*$", RegexOptions.IgnoreCase); if (m.Success) { // We use the name of the mof file (which is the same as the PDB file) as the provider name. if (string.IsNullOrEmpty(providerName)) { providerName = m.Groups[1].Value; } string mofFilePath; if (m_tmfDataFilePathsByFileNameBase.TryGetValue(providerName, out mofFilePath)) { if (mofFilePath.EndsWith(".mof", StringComparison.OrdinalIgnoreCase)) { using (var mofFile = File.OpenText(mofFilePath)) { for (; ;) { var mofLine = mofFile.ReadLine(); if (mofLine == null) { break; } m = Regex.Match(mofLine, @"guid\(.{(.*)}.\)", RegexOptions.IgnoreCase); if (m.Success) { try { providerGuid = new Guid(m.Groups[1].Value); } catch (Exception) { } break; } } } } } } } if (taskName == null) { // 7113b9e1-a0cc-d313-1eab-57efe9d7e56c build.server // SRC=TTSEngineCom.cpp MJ= MN= m = Regex.Match(line, @"^\w+-\w+-\w+-\w+-\w+\s+(\S+)"); if (m.Success) { taskName = m.Groups[1].Value; } } else { // #typev ttstracing_cpp78 13 "%0%10!s! Error happens in Initializing %11!s!!" // LEVEL=TRACE_LEVEL_ERROR FLAGS=TTS_Trace_Engine_Initialization FUNC=CTTSTracingHelper::LogComponentInitialization m = Regex.Match(line, "^#typev\\s+(\\S*?)(\\d+)\\s+(\\d+)\\s+\"(.*)\""); if (m.Success) { var fileName = m.Groups[1].Value; var lineNum = int.Parse(m.Groups[2].Value); var eventId = int.Parse(m.Groups[3].Value); var formatStr = m.Groups[4].Value; var eventProviderName = taskName; if (providerName != null) { eventProviderName = providerName + "/" + eventProviderName; } var template = new DynamicTraceEventData(null, eventId, 0, fileName + "/" + m.Groups[2].Value, taskGuid, 0, "", providerGuid, eventProviderName); template.lookupAsWPP = true; // Use WPP lookup convetions. formatStr = formatStr.Replace("%0", ""); // TODO What is this? Why is it here? formatStr = Regex.Replace(formatStr, @"%(\d+)!.!", delegate(Match match) { return("%" + (int.Parse(match.Groups[1].Value) - 9).ToString()); }); template.MessageFormat = formatStr; parameterTypes.Clear(); for (; ;) { line = tmfData.ReadLine(); if (line == null) { break; } if (line.Trim() == "}") { break; } // szPOSHeader, ItemString -- 10 m = Regex.Match(line, @"^\S+, Item(\w+) -- (\d+)"); if (m.Success) { var typeStr = m.Groups[1].Value; Type type = null; if (typeStr == "String") { type = typeof(string); } else if (typeStr == "Long") { type = typeof(int); } else if (typeStr == "Double") { type = typeof(double); } if (type != null) { parameterTypes.Add(type); } } } template.payloadNames = new string[parameterTypes.Count]; template.payloadFetches = new DynamicTraceEventData.PayloadFetch[parameterTypes.Count]; ushort offset = 0; for (int i = 0; i < parameterTypes.Count; i++) { template.payloadNames[i] = "Arg" + (i + 1).ToString(); template.payloadFetches[i].type = parameterTypes[i]; template.payloadFetches[i].offset = offset; var size = DynamicTraceEventData.SizeOfType(parameterTypes[i]); if (template.payloadFetches[i].type == typeof(string)) { size |= DynamicTraceEventData.IS_ANSI; } template.payloadFetches[i].size = size; if (size >= DynamicTraceEventData.SPECIAL_SIZES) { offset = ushort.MaxValue; // Indicate that the offset must be computed at run time. } else { offset += size; } } templates.Add(template); } } } } return(templates); }
private DynamicTraceEventData NewTemplate(Guid providerId, string providerName, uint eventId, string eventName, Tuple <TypeCode, string>[] parameterDefinitions) { int opcode; string opcodeName; GetOpcodeFromEventName(eventName, out opcode, out opcodeName); var template = new DynamicTraceEventData(null, (int)eventId, 0, eventName, Guid.Empty, opcode, opcodeName, providerId, providerName); if (parameterDefinitions != null && parameterDefinitions.Length > 0) { template.payloadNames = new string[parameterDefinitions.Length]; template.payloadFetches = new DynamicTraceEventData.PayloadFetch[parameterDefinitions.Length]; ushort offset = 0; for (int i = 0; i < parameterDefinitions.Length; i++) { template.payloadNames[i] = parameterDefinitions[i].Item2; var fetch = new DynamicTraceEventData.PayloadFetch(); switch (parameterDefinitions[i].Item1) { case TypeCode.Boolean: { fetch.Type = typeof(bool); fetch.Size = 4; // We follow windows conventions and use 4 bytes for bool. fetch.Offset = offset; break; } case TypeCode.Char: { fetch.Type = typeof(char); fetch.Size = sizeof(char); fetch.Offset = offset; break; } case TypeCode.SByte: { fetch.Type = typeof(SByte); fetch.Size = sizeof(SByte); fetch.Offset = offset; break; } case TypeCode.Byte: { fetch.Type = typeof(byte); fetch.Size = sizeof(byte); fetch.Offset = offset; break; } case TypeCode.Int16: { fetch.Type = typeof(Int16); fetch.Size = sizeof(Int16); fetch.Offset = offset; break; } case TypeCode.UInt16: { fetch.Type = typeof(UInt16); fetch.Size = sizeof(UInt16); fetch.Offset = offset; break; } case TypeCode.Int32: { fetch.Type = typeof(Int32); fetch.Size = sizeof(Int32); fetch.Offset = offset; break; } case TypeCode.UInt32: { fetch.Type = typeof(UInt32); fetch.Size = sizeof(UInt32); fetch.Offset = offset; break; } case TypeCode.Int64: { fetch.Type = typeof(Int64); fetch.Size = sizeof(Int64); fetch.Offset = offset; break; } case TypeCode.UInt64: { fetch.Type = typeof(UInt64); fetch.Size = sizeof(UInt64); fetch.Offset = offset; break; } case TypeCode.Single: { fetch.Type = typeof(Single); fetch.Size = sizeof(Single); fetch.Offset = offset; break; } case TypeCode.Double: { fetch.Type = typeof(Double); fetch.Size = sizeof(Double); fetch.Offset = offset; break; } case TypeCode.Decimal: { fetch.Type = typeof(Decimal); fetch.Size = sizeof(Decimal); fetch.Offset = offset; break; } case TypeCode.DateTime: { fetch.Type = typeof(DateTime); fetch.Size = 8; fetch.Offset = offset; break; } case TypeCode.String: { fetch.Type = typeof(String); fetch.Size = DynamicTraceEventData.NULL_TERMINATED; fetch.Offset = offset; break; } default: { throw new NotSupportedException($"{parameterDefinitions[i].Item1} is not supported."); } } if (fetch.Size >= DynamicTraceEventData.SPECIAL_SIZES || offset == ushort.MaxValue) { offset = ushort.MaxValue; // Indicate that the offset must be computed at run time. } else { offset += fetch.Size; } template.payloadFetches[i] = fetch; } } else { template.payloadNames = new string[0]; template.payloadFetches = new DynamicTraceEventData.PayloadFetch[0]; } return(template); }
internal bool TryGetTemplateFromMetadata(TraceEvent unhandledEvent, out DynamicTraceEventData template) { return(_metadataTemplates.TryGetValue(unhandledEvent, out template)); }
public void AddProviderEvents(ITraceParserServices source, Action <TraceEvent> callback) { if (error != null) { return; } if (!inited) { Init(); } try { Dictionary <string, int> opcodes = new Dictionary <string, int>(); opcodes.Add("win:Info", 0); opcodes.Add("win:Start", 1); opcodes.Add("win:Stop", 2); opcodes.Add("win:DC_Start", 3); opcodes.Add("win:DC_End", 4); opcodes.Add("win:Extension", 5); opcodes.Add("win:Reply", 6); opcodes.Add("win:Resume", 7); opcodes.Add("win:Suspend", 8); opcodes.Add("win:Send", 9); opcodes.Add("win:Receive", 240); Dictionary <string, TaskInfo> tasks = new Dictionary <string, TaskInfo>(); Dictionary <string, DynamicTraceEventData> templates = new Dictionary <string, DynamicTraceEventData>(); while (reader.Read()) { switch (reader.Name) { case "event": { int taskNum = 0; Guid taskGuid = Guid; string taskName = reader.GetAttribute("task"); if (taskName != null) { TaskInfo taskInfo; if (tasks.TryGetValue(taskName, out taskInfo)) { taskNum = taskInfo.id; taskGuid = taskInfo.guid; } } else { taskName = ""; } int opcode = 0; string opcodeName = reader.GetAttribute("opcode"); if (opcodeName != null) { opcode = opcodes[opcodeName]; // Strip off any namespace prefix int colon = opcodeName.IndexOf(':'); if (colon >= 0) { opcodeName = opcodeName.Substring(colon + 1); } } int eventID = int.Parse(reader.GetAttribute("value")); DynamicTraceEventData eventTemplate = new DynamicTraceEventData( callback, eventID, taskNum, taskName, taskGuid, opcode, opcodeName, Guid, Name); string templateName = reader.GetAttribute("template"); if (templateName != null) { templates[templateName] = eventTemplate; } else { eventTemplate.payloadNames = new string[0]; eventTemplate.payloadFetches = new DynamicTraceEventData.PayloadFetch[0]; source.RegisterEventTemplate(eventTemplate); } } break; case "template": { string templateName = reader.GetAttribute("tid"); Debug.Assert(templateName != null); DynamicTraceEventData eventTemplate = templates[templateName]; ComputeFieldInfo(eventTemplate, reader.ReadSubtree()); source.RegisterEventTemplate(eventTemplate); templates.Remove(templateName); } break; case "opcode": opcodes.Add(reader.GetAttribute("name"), int.Parse(reader.GetAttribute("value"))); break; case "task": { TaskInfo info = new TaskInfo(); info.id = int.Parse(reader.GetAttribute("value")); string guidString = reader.GetAttribute("eventGUID"); if (guidString != null) { info.guid = new Guid(guidString); } tasks.Add(reader.GetAttribute("name"), info); } break; } } foreach (DynamicTraceEventData eventTemplate in templates.Values) { eventTemplate.payloadNames = new string[0]; eventTemplate.payloadFetches = new DynamicTraceEventData.PayloadFetch[0]; source.RegisterEventTemplate(eventTemplate); } } catch (Exception e) { Debug.Assert(false, "Exception during manifest parsing"); Console.WriteLine("Error: Exception during processing, symbolic information not available"); error = e; } inited = false; // If we call it again, start over from the begining. }
protected override DynamicTraceEventData TryLookup(TraceEvent unknownEvent) { DynamicTraceEventData ret = null; // TODO react if 4K is not big enough, cache the buffer?, handle more types, handle structs... int buffSize = 4096; byte *buffer = (byte *)System.Runtime.InteropServices.Marshal.AllocHGlobal(buffSize); int status = TdhGetEventInformation(unknownEvent.eventRecord, 0, null, buffer, &buffSize); if (status == 0) { TRACE_EVENT_INFO * eventInfo = (TRACE_EVENT_INFO *)buffer; EVENT_PROPERTY_INFO *propertyInfos = &eventInfo->EventPropertyInfoArray; string taskName = null; if (eventInfo->TaskNameOffset != 0) { taskName = (new string((char *)(&buffer[eventInfo->TaskNameOffset]))).Trim(); } string opcodeName = null; if (eventInfo->OpcodeNameOffset != 0) { opcodeName = (new string((char *)(&buffer[eventInfo->OpcodeNameOffset]))).Trim(); if (opcodeName.StartsWith("win:")) { opcodeName = opcodeName.Substring(4); } } string providerName = "UnknownProvider"; if (eventInfo->ProviderNameOffset != 0) { providerName = new string((char *)(&buffer[eventInfo->ProviderNameOffset])); } var eventID = unknownEvent.ClassicProvider ? TraceEventID.Illegal : unknownEvent.eventID; var newTemplate = new DynamicTraceEventData(null, (int)eventID, (int)unknownEvent.task, taskName, unknownEvent.taskGuid, (int)unknownEvent.Opcode, opcodeName, unknownEvent.ProviderGuid, providerName); newTemplate.payloadNames = new string[eventInfo->TopLevelPropertyCount]; newTemplate.payloadFetches = new DynamicTraceEventData.PayloadFetch[eventInfo->TopLevelPropertyCount]; ushort offset = 0; for (int i = 0; i < eventInfo->TopLevelPropertyCount; i++) { var propertyInfo = &propertyInfos[i]; var propertyName = new string((char *)(&buffer[propertyInfo->NameOffset])); // Remove anything that does not look like an ID (.e.g space) newTemplate.payloadNames[i] = Regex.Replace(propertyName, "[^A-Za-z0-9_]", ""); newTemplate.payloadFetches[i].type = GetTypeForTdhInType(propertyInfo->InType); // Determine whether the size variable or not, and set 'size' based on that. ushort size = DynamicTraceEventData.UNKNOWN_SIZE; // is this dynamically sized with another field specifying the length? if ((propertyInfo->Flags & PROPERTY_FLAGS.ParamLength) != 0) { if (propertyInfo->LengthOrLengthIndex == i - 1) { if (propertyInfos[i - 1].LengthOrLengthIndex == 4) { size = DynamicTraceEventData.COUNT32_PRECEEDS; } else if (propertyInfos[i - 1].LengthOrLengthIndex == 2) { size = DynamicTraceEventData.COUNT16_PRECEEDS; } else { Trace.WriteLine("WARNING: Unexpected dynamic length, giving up"); } } if (size != DynamicTraceEventData.UNKNOWN_SIZE && propertyInfo->InType == TdhInputType.AnsiString) { size |= DynamicTraceEventData.IS_ANSI; } } else { if (propertyInfo->InType == TdhInputType.AnsiString) { size = DynamicTraceEventData.NULL_TERMINATED | DynamicTraceEventData.IS_ANSI; } else if (propertyInfo->InType == TdhInputType.UnicodeString) { size = DynamicTraceEventData.NULL_TERMINATED; } else if (propertyInfo->InType == TdhInputType.Pointer) { size = DynamicTraceEventData.POINTER_SIZE; } else { // No, then it it fixed size (but give up if it is too big) var fixedSize = propertyInfo->CountOrCountIndex * propertyInfo->LengthOrLengthIndex; if (fixedSize < 0x7FF0) { size = (ushort)fixedSize; if (propertyInfo->InType == TdhInputType.AnsiString) { size += 0x8000; } } } } // Currently we give up on any other flags (arrays, structs). if ((propertyInfo->Flags & ~PROPERTY_FLAGS.ParamLength) != 0) { size = DynamicTraceEventData.UNKNOWN_SIZE; } newTemplate.payloadFetches[i].size = (ushort)size; newTemplate.payloadFetches[i].offset = offset; if (size >= DynamicTraceEventData.SPECIAL_SIZES) { offset = ushort.MaxValue; // Indicate that the offset must be computed at run time. } else if (offset != ushort.MaxValue) { Debug.Assert(offset + size < ushort.MaxValue); offset += size; } } ret = newTemplate; // return this as the event template for this lookup. } System.Runtime.InteropServices.Marshal.FreeHGlobal((IntPtr)buffer); return(ret); }
public void AddProviderEvents(ITraceParserServices source, Action<TraceEvent> callback) { if (error != null) return; if (!inited) Init(); try { Dictionary<string, int> opcodes = new Dictionary<string, int>(); opcodes.Add("win:Info", 0); opcodes.Add("win:Start", 1); opcodes.Add("win:Stop", 2); opcodes.Add("win:DC_Start", 3); opcodes.Add("win:DC_End", 4); opcodes.Add("win:Extension", 5); opcodes.Add("win:Reply", 6); opcodes.Add("win:Resume", 7); opcodes.Add("win:Suspend", 8); opcodes.Add("win:Send", 9); opcodes.Add("win:Receive", 240); Dictionary<string, TaskInfo> tasks = new Dictionary<string, TaskInfo>(); Dictionary<string, DynamicTraceEventData> templates = new Dictionary<string, DynamicTraceEventData>(); while (reader.Read()) { // TODO I currently require opcodes,and tasks BEFORE events BEFORE templates. // Can be fixed by going multi-pass. switch (reader.Name) { case "event": { int taskNum = 0; Guid taskGuid = Guid; string taskName = reader.GetAttribute("task"); if (taskName != null) { TaskInfo taskInfo; if (tasks.TryGetValue(taskName, out taskInfo)) { taskNum = taskInfo.id; taskGuid = taskInfo.guid; } } else taskName = ""; int opcode = 0; string opcodeName = reader.GetAttribute("opcode"); if (opcodeName != null) { opcode = opcodes[opcodeName]; // Strip off any namespace prefix (TODO is this a good idea? int colon = opcodeName.IndexOf(':'); if (colon >= 0) opcodeName = opcodeName.Substring(colon + 1); } else { // TODO: Improve this. // If we don't have an opcode (which is bad, since it does not work on XP), opcodeName = reader.GetAttribute("name"); if (taskName != null && opcodeName.StartsWith(taskName)) opcodeName = opcodeName.Substring(taskName.Length); } int eventID = int.Parse(reader.GetAttribute("value")); DynamicTraceEventData eventTemplate = new DynamicTraceEventData( callback, eventID, taskNum, taskName, taskGuid, opcode, opcodeName, Guid, Name); string templateName = reader.GetAttribute("template"); if (templateName != null) templates[templateName] = eventTemplate; else { eventTemplate.payloadNames = new string[0]; eventTemplate.payloadFetches = new DynamicTraceEventData.PayloadFetch[0]; source.RegisterEventTemplate(eventTemplate); } } break; case "template": { string templateName = reader.GetAttribute("tid"); Debug.Assert(templateName != null); DynamicTraceEventData eventTemplate = templates[templateName]; try { ComputeFieldInfo(eventTemplate, reader.ReadSubtree()); } catch (Exception e) { Console.WriteLine("Error: Exception during processing template {0}: {1}", templateName, e.ToString()); throw; } source.RegisterEventTemplate(eventTemplate); templates.Remove(templateName); } break; case "opcode": opcodes.Add(reader.GetAttribute("name"), int.Parse(reader.GetAttribute("value"))); break; case "task": { TaskInfo info = new TaskInfo(); info.id = int.Parse(reader.GetAttribute("value")); string guidString = reader.GetAttribute("eventGUID"); if (guidString != null) info.guid = new Guid(guidString); tasks.Add(reader.GetAttribute("name"), info); } break; } } // TODO Register any events with undefined templates as having empty payloads (can rip out after 1/2009) foreach (DynamicTraceEventData eventTemplate in templates.Values) { eventTemplate.payloadNames = new string[0]; eventTemplate.payloadFetches = new DynamicTraceEventData.PayloadFetch[0]; source.RegisterEventTemplate(eventTemplate); } } catch (Exception e) { Debug.Assert(false, "Exception during manifest parsing"); Console.WriteLine("Error: Exception during processing of in-log manifest for provider {0}. Symbolic information may not be complete.", Name); error = e; } inited = false; // If we call it again, start over from the begining. }
private void ComputeFieldInfo(DynamicTraceEventData template, XmlReader reader) { List<string> payloadNames = new List<string>(); List<DynamicTraceEventData.PayloadFetch> payloadFetches = new List<DynamicTraceEventData.PayloadFetch>(); short offset = 0; while (reader.Read()) { if (reader.Name == "data") { Type type = GetTypeForManifestTypeName(reader.GetAttribute("inType")); short size = DynamicTraceEventData.SizeOfType(type); // TODO There is disagreement in what win:Boolean means. Currently it is serialized as 1 byte // by manage code. However all other windows tools assume it is 4 bytes. we are likely // to change this to align with windows at some point. payloadNames.Add(reader.GetAttribute("name")); payloadFetches.Add(new DynamicTraceEventData.PayloadFetch(offset, size, type)); if (offset >= 0) { Debug.Assert(size != 0); if (size >= 0) offset += size; else offset = short.MinValue; } } } template.payloadNames = payloadNames.ToArray(); template.payloadFetches = payloadFetches.ToArray(); }
private List <DynamicTraceEventData> CreateTemplatesForTMFFile(Guid taskGuid, string tmfPath) { List <DynamicTraceEventData> templates = new List <DynamicTraceEventData>(); List <TypeAndFormat> parameterTypes = new List <TypeAndFormat>(); using (StreamReader tmfData = File.OpenText(tmfPath)) { string taskName = null; string providerName = null; Guid providerGuid = Guid.Empty; Match m; for (; ;) { var line = tmfData.ReadLine(); if (line == null) { break; } if (providerGuid == Guid.Empty) { m = Regex.Match(line, @"PDB: .*?(\w+)\.pdb\s*$", RegexOptions.IgnoreCase); if (m.Success) { // We use the name of the mof file (which is the same as the PDB file) as the provider name. if (string.IsNullOrEmpty(providerName)) { providerName = m.Groups[1].Value; } string mofFilePath; if (m_tmfDataFilePathsByFileNameBase.TryGetValue(providerName, out mofFilePath)) { if (mofFilePath.EndsWith(".mof", StringComparison.OrdinalIgnoreCase)) { using (var mofFile = File.OpenText(mofFilePath)) { for (; ;) { var mofLine = mofFile.ReadLine(); if (mofLine == null) { break; } m = Regex.Match(mofLine, @"guid\(.{(.*)}.\)", RegexOptions.IgnoreCase); if (m.Success) { try { providerGuid = new Guid(m.Groups[1].Value); } catch (Exception) { } break; } } } } } } } if (taskName == null) { // 7113b9e1-a0cc-d313-1eab-57efe9d7e56c build.server // SRC=TTSEngineCom.cpp MJ= MN= m = Regex.Match(line, @"^\w+-\w+-\w+-\w+-\w+\s+(\S+)"); if (m.Success) { taskName = m.Groups[1].Value; } } else { // #typev ttstracing_cpp78 13 "%0%10!s! Error happens in Initializing %11!s!!" // LEVEL=TRACE_LEVEL_ERROR FLAGS=TTS_Trace_Engine_Initialization FUNC=CTTSTracingHelper::LogComponentInitialization m = Regex.Match(line, "^#typev\\s+(\\S*?)(\\d+)\\s+(\\d+)\\s+\"(.*)\"(.*)"); if (m.Success) { var fileName = m.Groups[1].Value; var lineNum = int.Parse(m.Groups[2].Value); var eventId = int.Parse(m.Groups[3].Value); var formatStr = m.Groups[4].Value; // Substitute in %!NAME! for their values as defined in the tail if (formatStr.Contains("%!")) { var tail = m.Groups[5].Value; for (; ;) { var m1 = Regex.Match(formatStr, @"%!(\w+)!"); if (!m1.Success) { break; } var varName = m1.Groups[1].Value; var varValue = ""; m1 = Regex.Match(tail, varName + @"=(.*)"); if (m1.Success) { varValue = m1.Groups[1].Value; varValue = Regex.Replace(varValue, @" \w+=.*", ""); // Remove things that look like the next key-value } formatStr = formatStr.Replace("%!" + varName + "!", varValue); } } var eventProviderName = taskName; if (providerName != null) { eventProviderName = providerName + "/" + eventProviderName; } var template = new DynamicTraceEventData(null, eventId, 0, fileName + "/" + m.Groups[2].Value, taskGuid, 0, "", providerGuid, eventProviderName); template.lookupAsWPP = true; // Use WPP lookup conventions. parameterTypes.Clear(); for (; ;) { line = tmfData.ReadLine(); if (line == null) { break; } if (line.Trim() == "}") { break; } // szPOSHeader, ItemString -- 10 m = Regex.Match(line, @"^.*, Item(\S+) -- (\d+)$"); if (m.Success) { var typeStr = m.Groups[1].Value; Type type = null; IDictionary <long, string> map = null; if (typeStr == "String") { type = typeof(StringBuilder); // We use StringBuild to represent a ANSI string } else if (typeStr == "WString") { type = typeof(string); } else if (typeStr == "Long" || typeStr == "Ulong") { type = typeof(int); } else if (typeStr == "HRESULT" || typeStr == "NTSTATUS") { type = typeof(int); // By making map non-null we indicate that this is a enum, but we don't add any enum // mappings, which makes it print as Hex. Thus we are just saying 'print as hex' map = new SortedDictionary <long, string>(); } else if (typeStr == "Double") { type = typeof(double); } else if (typeStr == "Ptr") { type = typeof(IntPtr); } else if (typeStr.StartsWith("Enum(")) // TODO more support for enums { type = typeof(int); } else if (typeStr == "ULongLong" || typeStr.StartsWith("LongLong")) { type = typeof(long); } else if (typeStr == "ListLong(false,true)") { type = typeof(bool); } else if (typeStr.StartsWith("ListLong(")) { type = typeof(int); } else if (typeStr == "Guid") { type = typeof(Guid); } if (type != null) { parameterTypes.Add(new TypeAndFormat(type, map)); } } } template.payloadNames = new string[parameterTypes.Count]; template.payloadFetches = new DynamicTraceEventData.PayloadFetch[parameterTypes.Count]; ushort offset = 0; for (int i = 0; i < parameterTypes.Count; i++) { template.payloadNames[i] = "Arg" + (i + 1).ToString(); template.payloadFetches[i].Offset = offset; var type = parameterTypes[i].Type; template.payloadFetches[i].Map = parameterTypes[i].Map; ushort size = 0; if (type == typeof(StringBuilder)) // This mean ANSI_STRING (I just need a distinct type) { type = typeof(string); size |= DynamicTraceEventData.IS_ANSI; } size |= DynamicTraceEventData.SizeOfType(type); template.payloadFetches[i].Size = size; template.payloadFetches[i].Type = type; if (size >= DynamicTraceEventData.SPECIAL_SIZES || offset == ushort.MaxValue) { offset = ushort.MaxValue; // Indicate that the offset must be computed at run time. } else { offset += size; } } formatStr = formatStr.Replace("%0", ""); // TODO What is this? Why is it here? formatStr = Regex.Replace(formatStr, @"%(\d+)!(\w?)\w*!", delegate(Match match) { var argNum = int.Parse(match.Groups[1].Value) - 10; // 0 first arg ... // If it has a !x qualifer after it change th map so it will be decoded as hex. if (match.Groups[2].Value == "x" && 0 <= argNum && argNum < template.payloadFetches.Length && template.payloadFetches[argNum].Map == null) { template.payloadFetches[argNum].Map = new SortedDictionary <long, string>(); } return("%" + (argNum + 1).ToString()); }); template.MessageFormat = formatStr; templates.Add(template); } } } } return(templates); }