예제 #1
0
        private unsafe bool CustomParserLookup(EVENT_RECORD *eventRecord, ref TraceEventKey key)
        {
            bool success;

            // events added by KernelTraceControl.dll (i.e. Microsoft tools like WPR and PerfView)
            if (eventRecord->ProviderId == CustomParserGuids.KernelTraceControlImageIdGuid)
            {
                switch (eventRecord->Opcode)
                {
                case 0:
                    this.actionTable.Add(key, new KernelTraceControlImageIdParser().Parse);
                    success = true;
                    break;

                case 36:
                    this.actionTable.Add(key, new KernelTraceControlDbgIdParser().Parse);
                    success = true;
                    break;

                case 64:
                    this.actionTable.Add(key, new KernelTraceControlImageIdFileVersionParser().Parse);
                    success = true;
                    break;

                default:
                    success = false;
                    break;
                }
            }

            // events by the Kernel Stack Walker (need this because the MOF events always says 32 stacks, but in reality there can be fewer or more
            else if (eventRecord->ProviderId == CustomParserGuids.KernelStackWalkGuid)
            {
                if (eventRecord->Opcode == 32)
                {
                    this.actionTable.Add(key, new KernelStackWalkEventParser().Parse);
                    success = true;
                }
                else
                {
                    success = false;
                }
            }
            else
            {
                success = false;
            }

            return(success);
        }
예제 #2
0
        public unsafe void Deserialize(EVENT_RECORD *eventRecord)
        {
            eventRecord->UserDataFixed = eventRecord->UserData;
            var eventRecordReader = new EventRecordReader(eventRecord);
            var runtimeMetadata   = new RuntimeEventMetadata(eventRecord);

            var key = new TraceEventKey(
                eventRecord->ProviderId,
                (eventRecord->Flags & Etw.EVENT_HEADER_FLAG_CLASSIC_HEADER) != 0 ? eventRecord->Opcode : eventRecord->Id,
                eventRecord->Version);

            Action <EventRecordReader, T, EventMetadata[], RuntimeEventMetadata> action;

            if (this.actionTable.TryGetValue(key, out action))
            {
                action(eventRecordReader, this.writer, this.eventMetadataTable, runtimeMetadata);
            }
            else
            {
                this.SlowLookup(eventRecord, eventRecordReader, runtimeMetadata, ref key);
            }
        }
예제 #3
0
        private unsafe void SlowLookup(EVENT_RECORD *eventRecord, EventRecordReader eventRecordReader, RuntimeEventMetadata runtimeMetadata, ref TraceEventKey key)
        {
            if (this.CustomParserLookup(eventRecord, ref key))
            {
                return;
            }

            bool isSpecialKernelTraceMetaDataEvent = false;
            var  operand = this.BuildOperand(eventRecord, eventRecordReader, this.eventMetadataTableList.Count, ref isSpecialKernelTraceMetaDataEvent);

            if (operand != null)
            {
                this.eventMetadataTableList.Add(operand.Metadata);
                this.eventMetadataTable = this.eventMetadataTableList.ToArray(); // TODO: Need to improve this

                var eventRecordReaderParam  = Expression.Parameter(ReaderType);
                var eventWriterParam        = Expression.Parameter(WriterType);
                var eventMetadataTableParam = Expression.Parameter(EventMetadataArrayType);
                var runtimeMetadataParam    = Expression.Parameter(RuntimeMetadataType);

                var parameters = new[] { eventRecordReaderParam, eventWriterParam, eventMetadataTableParam, runtimeMetadataParam };
                var name       = Regex.Replace(InvalidCharacters.Replace(operand.Metadata.Name, "_"), @"\s+", "_");
                var body       = EventTraceOperandExpressionBuilder.Build(operand, eventRecordReaderParam, eventWriterParam, eventMetadataTableParam, runtimeMetadataParam);
                LambdaExpression expression = Expression.Lambda <Action <EventRecordReader, T, EventMetadata[], RuntimeEventMetadata> >(body, "Read_" + name, parameters);
                var action = (Action <EventRecordReader, T, EventMetadata[], RuntimeEventMetadata>)expression.Compile(false);

                if (isSpecialKernelTraceMetaDataEvent)
                {
                    var e = (TRACE_EVENT_INFO *)eventRecord->UserDataFixed;
                    this.actionTable.AddOrUpdate(new TraceEventKey(e->ProviderGuid, e->EventGuid == Guid.Empty ? e->Id : e->Opcode, e->Version), action);
                }
                else
                {
                    this.actionTable.Add(key, action);
                    action(eventRecordReader, this.writer, this.eventMetadataTable, runtimeMetadata);
                }
            }
        }
예제 #4
0
        private unsafe void SlowLookup(EVENT_RECORD *eventRecord, EventRecordReader eventRecordReader, RuntimeEventMetadata runtimeMetadata, ref TraceEventKey key)
        {
            if (this.CustomParserLookup(eventRecord, ref key))
            {
                return;
            }

            bool isSpecialKernelTraceMetaDataEvent = false;
            var  operand = this.BuildOperand(eventRecord, eventRecordReader, this.eventMetadataTableList.Count, ref isSpecialKernelTraceMetaDataEvent);

            if (operand != null)
            {
                this.eventMetadataTableList.Add(operand.Metadata);
                this.eventMetadataTable = this.eventMetadataTableList.ToArray(); // TODO: Need to improve this

                var eventRecordReaderParam  = Expression.Parameter(ReaderType);
                var eventWriterParam        = Expression.Parameter(WriterType);
                var eventMetadataTableParam = Expression.Parameter(EventMetadataArrayType);
                var runtimeMetadataParam    = Expression.Parameter(RuntimeMetadataType);

                var parameters = new[] { eventRecordReaderParam, eventWriterParam, eventMetadataTableParam, runtimeMetadataParam };
                var name       = Regex.Replace(InvalidCharacters.Replace(operand.Metadata.Name, "_"), @"\s+", "_");
                var body       = EventTraceOperandExpressionBuilder.Build(operand, eventRecordReaderParam, eventWriterParam, eventMetadataTableParam, runtimeMetadataParam);
                LambdaExpression expression = Expression.Lambda <Action <EventRecordReader, T, EventMetadata[], RuntimeEventMetadata> >(body, "Read_" + name, parameters);

                var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(name), AssemblyBuilderAccess.RunAndCollect);
                var moduleBuilder   = assemblyBuilder.DefineDynamicModule(name, name + ".dll");

                var typeBuilder   = moduleBuilder.DefineType(name, TypeAttributes.Public);
                var methodBuilder = typeBuilder.DefineMethod("Read", MethodAttributes.Public | MethodAttributes.Static, typeof(void), new[] { ReaderType, WriterType, EventMetadataArrayType, RuntimeMetadataType });

                expression.CompileToMethod(methodBuilder);
                var action = (Action <EventRecordReader, T, EventMetadata[], RuntimeEventMetadata>)Delegate.CreateDelegate(expression.Type, typeBuilder.CreateType().GetMethod("Read"));

                if (isSpecialKernelTraceMetaDataEvent)
                {
                    var e = (TRACE_EVENT_INFO *)eventRecord->UserDataFixed;
                    this.actionTable.AddOrUpdate(new TraceEventKey(e->ProviderGuid, e->EventGuid == Guid.Empty ? e->Id : e->Opcode, e->Version), action);
                }
                else
                {
                    this.actionTable.Add(key, action);
                    action(eventRecordReader, this.writer, this.eventMetadataTable, runtimeMetadata);
                }
            }
        }