Пример #1
0
        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);
        }
Пример #2
0
        /// <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);
        }
Пример #4
0
        /// <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);
        }
Пример #5
0
    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();
    }
Пример #6
0
 /// <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);
 }
Пример #7
0
        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);
        }
Пример #8
0
        /// <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);
        }
Пример #9
0
        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);
        }
Пример #10
0
        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);
        }
Пример #11
0
 internal bool TryGetTemplateFromMetadata(TraceEvent unhandledEvent, out DynamicTraceEventData template)
 {
     return(_metadataTemplates.TryGetValue(unhandledEvent, out template));
 }
 /// <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);
 }
Пример #13
0
    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);
        }
Пример #15
0
    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.
    }
Пример #16
0
    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();
    }
Пример #17
0
        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);
        }