Ejemplo n.º 1
0
        /// <summary>
        /// This method is the callback used by GetSessions() when it calls into GetSessionInfo().
        /// It updates a List<SessionInfo> based on the etwSessionId and matchAllKeywords that
        /// GetSessionInfo() passes in.
        /// </summary>
        private static void GetSessionInfoCallback(int etwSessionId, long matchAllKeywords,
                                                   ref List <SessionInfo> sessionList)
        {
            uint sessionIdBitMask = (uint)SessionMask.FromEventKeywords((ulong)matchAllKeywords);

            // an ETW controller that specifies more than the mandated bit for our EventSource
            // will be ignored...
            if (bitcount(sessionIdBitMask) > 1)
            {
                return;
            }

            if (sessionList == null)
            {
                sessionList = new List <SessionInfo>(8);
            }

            if (bitcount(sessionIdBitMask) == 1)
            {
                // activity-tracing-aware etw session
                sessionList.Add(new SessionInfo(bitindex(sessionIdBitMask) + 1, etwSessionId));
            }
            else
            {
                // legacy etw session
                sessionList.Add(new SessionInfo(bitcount((uint)SessionMask.All) + 1, etwSessionId));
            }
        }
        // Token: 0x06003343 RID: 13123 RVA: 0x000C2DE0 File Offset: 0x000C0FE0
        private static void GetSessionInfoCallback(int etwSessionId, long matchAllKeywords, ref List <EventProvider.SessionInfo> sessionList)
        {
            uint n = (uint)SessionMask.FromEventKeywords((ulong)matchAllKeywords);

            if (EventProvider.bitcount(n) > 1)
            {
                return;
            }
            if (sessionList == null)
            {
                sessionList = new List <EventProvider.SessionInfo>(8);
            }
            if (EventProvider.bitcount(n) == 1)
            {
                sessionList.Add(new EventProvider.SessionInfo(EventProvider.bitindex(n) + 1, etwSessionId));
                return;
            }
            sessionList.Add(new EventProvider.SessionInfo(EventProvider.bitcount((uint)SessionMask.All) + 1, etwSessionId));
        }
Ejemplo n.º 3
0
 internal void WriteStringToListener(EventListener listener, string msg, SessionMask m)
 {
     Contract.Assert(listener == null || (uint)m == (uint)SessionMask.FromId(0));
     
     if (m_eventSourceEnabled)
     {
         if (listener == null)
         {
             WriteEventString(0, (long) m.ToEventKeywords(), msg);
         }
         else
         {
             List<object> arg = new List<object>();
             arg.Add(msg);
             EventWrittenEventArgs eventCallbackArgs = new EventWrittenEventArgs(this);
             eventCallbackArgs.EventId = 0;
             eventCallbackArgs.Payload = new ReadOnlyCollection<object>(arg);
             listener.OnEventWritten(eventCallbackArgs);
         }
     }
 }
Ejemplo n.º 4
0
        private void Initialize(Guid eventSourceGuid, string eventSourceName)
        {
            if (eventSourceGuid == Guid.Empty)
            {
                throw new ArgumentException(Environment.GetResourceString("EventSource_NeedGuid"));
            }

            if (eventSourceName == null)
            {
                throw new ArgumentException(Environment.GetResourceString("EventSource_NeedName"));
            }

            m_name = eventSourceName;
            m_guid = eventSourceGuid;
#if FEATURE_ACTIVITYSAMPLING
            m_curLiveSessions = new SessionMask(0);
            m_etwSessionIdMap = new EtwSession[SessionMask.MAX];
#endif // FEATURE_ACTIVITYSAMPLING

#if FEATURE_MANAGED_ETW
            m_provider = new OverideEventProvider(this);

            try
            {
                m_provider.Register(eventSourceGuid);
            }
            catch (ArgumentException)
            {
                // Failed to register.  Don't crash the app, just don't write events to ETW.
                m_provider = null;
            }
#endif
            // Add the eventSource to the global (weak) list.  This also sets m_id, which is the
            // index in the list. 
            EventListener.AddEventSource(this);

            // We are logically completely initialized at this point.  
            m_completelyInited = true;

            // report any possible errors
            ReportOutOfBandMessage(null, true);

#if FEATURE_ACTIVITYSAMPLING
            // we cue sending sampling info here based on whether we had to defer sending
            // the manifest
            // note: we do *not* send sampling info to any EventListeners because
            // the following common code pattern would cause an AV:
            // class MyEventSource: EventSource
            // {
            //    public static EventSource Log; 
            // }
            // class MyEventListener: EventListener
            // {
            //    protected override void OnEventWritten(...)
            //    { MyEventSource.Log.anything; } <-- AV, as the static Log was not set yet
            // }
            if (m_eventSourceEnabled && m_deferedSendManifest)
                ReportActivitySamplingInfo(null, m_curLiveSessions);
#endif // FEATURE_ACTIVITYSAMPLING

            // If we are active and we have not sent our manifest, do so now.  
            if (m_eventSourceEnabled && m_deferedSendManifest)
                SendManifest(m_rawManifest);
        }
Ejemplo n.º 5
0
 internal void WriteString(string msg, SessionMask m)
 {
     if (m_eventSourceEnabled)
     {
         WriteEventString(0, (long) m.ToEventKeywords(), msg);
         WriteStringToAllListeners(msg);
     }
 }
Ejemplo n.º 6
0
 public SessionMask(SessionMask m)
 { m_mask = m.m_mask; }
Ejemplo n.º 7
0
 public bool IsEqualOrSupersetOf(SessionMask m)
 {
     return (this.m_mask | m.m_mask) == this.m_mask;
 }
Ejemplo n.º 8
0
        private void ReportActivitySamplingInfo(EventListener listener, SessionMask sessions)
        {
            Contract.Assert(listener == null || (uint)sessions == (uint)SessionMask.FromId(0));

            for (int perEventSourceSessionId = 0; perEventSourceSessionId < SessionMask.MAX; ++perEventSourceSessionId)
            {
                if (!sessions[perEventSourceSessionId])
                    continue;

                ActivityFilter af;
                if (listener == null)
                {
                    EtwSession etwSession = m_etwSessionIdMap[perEventSourceSessionId];
                    Contract.Assert(etwSession != null);
                    af = etwSession.m_activityFilter;
                }
                else
                {
                    af = listener.m_activityFilter;
                }

                if (af == null)
                    continue;

                SessionMask m = new SessionMask(); 
                m[perEventSourceSessionId] = true;

                foreach (var t in af.GetFilterAsTuple(m_guid))
                {
                    WriteStringToListener(listener, string.Format(CultureInfo.InvariantCulture, "Session {0}: {1} = {2}", perEventSourceSessionId, t.Item1, t.Item2), m);
                }

                bool participateInSampling = (listener == null) ? 
                                               m_activityFilteringForETWEnabled[perEventSourceSessionId] : 
                                               GetDispatcher(listener).m_activityFilteringEnabled;
                WriteStringToListener(listener, string.Format(CultureInfo.InvariantCulture, "Session {0}: Activity Sampling support: {1}", 
                                          perEventSourceSessionId, participateInSampling ? "enabled" : "disabled"), m);
            }
        }
Ejemplo n.º 9
0
        // This is the internal entry point that code:EventListeners call when wanting to send a command to a
        // eventSource. The logic is as follows
        // 
        // * if Command == Update
        //     * perEventSourceSessionId specifies the per-provider ETW session ID that the command applies 
        //         to (if listener != null)
        //         perEventSourceSessionId = 0 - reserved for EventListeners
        //         perEventSourceSessionId = 1..SessionMask.MAX - reserved for activity tracing aware ETW sessions
        //                  perEventSourceSessionId-1 represents the bit in the reserved field (bits 44..47) in 
        //                  Keywords that identifies the session
        //         perEventSourceSessionId = SessionMask.MAX+1 - reserved for legacy ETW sessions; these are 
        //                  discriminated by etwSessionId
        //     * etwSessionId specifies a machine-wide ETW session ID; this allows correlation of
        //         activity tracing across different providers (which might have different sessionIds
        //         for the same ETW session)
        //     * enable, level, matchAnyKeywords are used to set a default for all events for the
        //         eventSource.  In particular, if 'enabled' is false, 'level' and
        //         'matchAnyKeywords' are not used.  
        //     * OnEventCommand is invoked, which may cause calls to
        //         code:EventSource.EnableEventForDispatcher which may cause changes in the filtering
        //         depending on the logic in that routine.
        // * else (command != Update)
        //     * Simply call OnEventCommand. The expectation is that filtering is NOT changed.
        //     * The 'enabled' 'level', matchAnyKeyword' arguments are ignored (must be true, 0, 0).  
        // 
        // dispatcher == null has special meaning. It is the 'ETW' dispatcher.
        internal void SendCommand(EventListener listener, int perEventSourceSessionId, int etwSessionId,
                                  EventCommand command, bool enable, 
                                  EventLevel level, EventKeywords matchAnyKeyword, 
                                  IDictionary<string, string> commandArguments)
        {
            m_lastCommandException = null;
            bool shouldReport = (perEventSourceSessionId > 0) && (perEventSourceSessionId <= SessionMask.MAX);

            try
            {
                lock (EventListener.EventListenersLock)
                {
                    EnsureInitialized();

                    // Find the per-EventSource dispatcher cooresponding to registered dispatcher
                    EventDispatcher eventSourceDispatcher = GetDispatcher(listener);
                    if (eventSourceDispatcher == null && listener != null)     // dispatcher == null means ETW dispatcher
                        throw new ArgumentException(Environment.GetResourceString("EventSource_ListenerNotFound"));

                    if (commandArguments == null)
                        commandArguments = new Dictionary<string, string>();

                    if (command == EventCommand.Update)
                    {
                        // Set it up using the 'standard' filtering bitfields (use the "global" enable, not session specific one)
                        for (int i = 0; i < m_eventData.Length; i++)
                            EnableEventForDispatcher(eventSourceDispatcher, i, IsEnabledByDefault(i, enable, level, matchAnyKeyword));

                        if (enable)
                        {
                            if (!m_eventSourceEnabled)
                            {
                                // EventSource turned on for the first time, simply copy the bits.  
                                m_level = level;
                                m_matchAnyKeyword = matchAnyKeyword;
                            }
                            else
                            {
                                // Already enabled, make it the most verbose of the existing and new filter
                                if (level > m_level)
                                    m_level = level;
                                if (matchAnyKeyword == 0)
                                    m_matchAnyKeyword = 0;
                                else if (m_matchAnyKeyword != 0)
                                    m_matchAnyKeyword |= matchAnyKeyword;
                            }
                        }

                        // interpret perEventSourceSessionId's sign, and adjust perEventSourceSessionId to 
                        // represent 0-based positive values
                        bool bSessionEnable = (perEventSourceSessionId >= 0);
                        if (perEventSourceSessionId == 0 && enable == false)
                            bSessionEnable = false;

                        if (listener == null)
                        {
                            if (!bSessionEnable) 
                                perEventSourceSessionId = -perEventSourceSessionId;
                            // for "global" enable/disable (passed in with listener == null and
                            //  perEventSourceSessionId == 0) perEventSourceSessionId becomes -1
                            --perEventSourceSessionId;
                        }

                        command = bSessionEnable ? EventCommand.Enable : EventCommand.Disable;

                        // perEventSourceSessionId = -1 when ETW sent a notification, but the set of active sessions
                        // hasn't changed.
                        // sesisonId = SessionMask.MAX when one of the legacy ETW sessions changed
                        // 0 <= perEventSourceSessionId < SessionMask.MAX for activity-tracing aware sessions
                        Contract.Assert(perEventSourceSessionId >= -1 && perEventSourceSessionId <= SessionMask.MAX);

                        // Send the manifest if we are enabling an ETW session
                        if (bSessionEnable && eventSourceDispatcher == null)
                        {
                            // eventSourceDispatcher == null means this is the ETW manifest

                            // SendCommand can be called from the EventSource constructor as a side effect of 
                            // ETW registration.   Unfortunately when this callback is active the provider is
                            // not actually enabled (WriteEvents will fail).   Thus if we detect this condition
                            // (that we are still being constructed), we simply skip sending the manifest.  
                            // When the constructor completes we will try again and send the manifest at that time. 
                            //
                            // Note that we unconditionally send the manifest whenever we are enabled, even if
                            // we were already enabled.   This is because there may be multiple sessions active
                            // and we can't know that all the sessions have seen the manifest.  
                            if (m_completelyInited)
                                SendManifest(m_rawManifest);
                            else
                                m_deferedSendManifest = true;
                        }

#if FEATURE_ACTIVITYSAMPLING
                        if (bSessionEnable && perEventSourceSessionId != -1)
                        {
                            bool participateInSampling = false;
                            string activityFilters;
                            int sessionIdBit;

                            ParseCommandArgs(commandArguments, out participateInSampling, 
                                            out activityFilters, out sessionIdBit);

                            if (listener == null && commandArguments.Count > 0 && perEventSourceSessionId != sessionIdBit)
                            {
                                throw new ArgumentException(Environment.GetResourceString("EventSource_SessionIdError", 
                                                            perEventSourceSessionId+SessionMask.SHIFT_SESSION_TO_KEYWORD,
                                                            sessionIdBit+SessionMask.SHIFT_SESSION_TO_KEYWORD));
                            }

                            if (listener == null)
                            {
                                UpdateEtwSession(perEventSourceSessionId, etwSessionId, true, activityFilters, participateInSampling);
                            }
                            else
                            {
                                ActivityFilter.UpdateFilter(ref listener.m_activityFilter, this, 0, activityFilters);
                                eventSourceDispatcher.m_activityFilteringEnabled = participateInSampling;
                            }
                        }
                        else if (!bSessionEnable && listener == null)
                        {
                            // if we disable an ETW session, indicate that in a synthesized command argument
                            if (perEventSourceSessionId >= 0 && perEventSourceSessionId < SessionMask.MAX)
                            {
                                commandArguments["EtwSessionKeyword"] = (perEventSourceSessionId+SessionMask.SHIFT_SESSION_TO_KEYWORD).ToString(CultureInfo.InvariantCulture);
                            }
                        }
#endif // FEATURE_ACTIVITYSAMPLING

                        this.OnEventCommand(new EventCommandEventArgs(command, commandArguments, this, eventSourceDispatcher));

#if FEATURE_ACTIVITYSAMPLING
                        if (listener == null && !bSessionEnable && perEventSourceSessionId != -1)
                        {
                            // if we disable an ETW session, complete disabling it
                            UpdateEtwSession(perEventSourceSessionId, etwSessionId, false, null, false);
                        }
#endif // FEATURE_ACTIVITYSAMPLING

                        if (enable)
                        {
                            m_eventSourceEnabled = true;
                        }
                        else
                        {
                            // If we are disabling, maybe we can turn on 'quick checks' to filter
                            // quickly.  These are all just optimizations (since later checks will still filter)

#if FEATURE_ACTIVITYSAMPLING
                            // Turn off (and forget) any information about Activity Tracing.  
                            if (listener == null)
                            {
                                // reset all filtering information for activity-tracing-aware sessions
                                for (int i = 0; i < SessionMask.MAX; ++i)
                                {
                                    EtwSession etwSession = m_etwSessionIdMap[i];
                                    if (etwSession != null)
                                        ActivityFilter.DisableFilter(ref etwSession.m_activityFilter, this);
                                }
                                m_activityFilteringForETWEnabled = new SessionMask(0);
                                m_curLiveSessions = new SessionMask(0);
                                // reset activity-tracing-aware sessions
                                if (m_etwSessionIdMap != null)
                                    for (int i = 0; i < SessionMask.MAX; ++i)
                                        m_etwSessionIdMap[i] = null;
                                // reset legacy sessions
                                if (m_legacySessions != null)
                                    m_legacySessions.Clear();
                            }
                            else
                            {
                                ActivityFilter.DisableFilter(ref listener.m_activityFilter, this);
                                eventSourceDispatcher.m_activityFilteringEnabled = false;
                            }
#endif // FEATURE_ACTIVITYSAMPLING

                            // There is a good chance EnabledForAnyListener are not as accurate as
                            // they could be, go ahead and get a better estimate.  
                            for (int i = 0; i < m_eventData.Length; i++)
                            {
                                bool isEnabledForAnyListener = false;
                                for (EventDispatcher dispatcher = m_Dispatchers; dispatcher != null; dispatcher = dispatcher.m_Next)
                                {
                                    if (dispatcher.m_EventEnabled[i])
                                    {
                                        isEnabledForAnyListener = true;
                                        break;
                                    }
                                }
                                m_eventData[i].EnabledForAnyListener = isEnabledForAnyListener;
                            }

                            // If no events are enabled, disable the global enabled bit.
                            if (!AnyEventEnabled())
                            {
                                m_level = 0;
                                m_matchAnyKeyword = 0;
                                m_eventSourceEnabled = false;
                            }
                        }
#if FEATURE_ACTIVITYSAMPLING
                        UpdateKwdTriggers(enable);
#endif // FEATURE_ACTIVITYSAMPLING
                    }
                    else
                    {
                        if (command == EventCommand.SendManifest)
                            SendManifest(m_rawManifest);

                        // These are not used for non-update commands and thus should always be 'default' values
                        Contract.Assert(enable == true);
                        Contract.Assert(m_level == EventLevel.LogAlways);
                        Contract.Assert(m_matchAnyKeyword == EventKeywords.None);

                        this.OnEventCommand(new EventCommandEventArgs(command, commandArguments, null, null));
                    }

#if FEATURE_ACTIVITYSAMPLING
                    if (m_completelyInited && (listener != null || shouldReport))
                    {
                        SessionMask m = SessionMask.FromId(perEventSourceSessionId); 
                        ReportActivitySamplingInfo(listener, m);
                    }
                    OutputDebugString(string.Format(CultureInfo.InvariantCulture, "{0}.SendCommand(session {1}, cmd {2}, enable {3}, level {4}): live sessions {5:x}, sampling {6:x}", 
                                      m_name, perEventSourceSessionId, command, enable, level, 
                                      (ulong) m_curLiveSessions, (ulong) m_activityFilteringForETWEnabled));
#endif // FEATURE_ACTIVITYSAMPLING
                }
            }
            catch (Exception e)
            {
                // Remember any exception and rethrow.  
                m_lastCommandException = e;
                throw;
            }
        }
Ejemplo n.º 10
0
        unsafe private SessionMask GetEtwSessionMask(int eventId, Guid* childActivityID)
        {
            SessionMask etwSessions = new SessionMask();

            for (int i = 0; i < SessionMask.MAX; ++i)
            {
                EtwSession etwSession = m_etwSessionIdMap[i];
                if (etwSession != null)
                {
                    ActivityFilter activityFilter = etwSession.m_activityFilter;
                    // PassesActivityFilter() will flow "interesting" activities, so make sure
                    // to perform this test first, before ORing with ~m_activityFilteringForETWEnabled
                    // (note: the first test for !m_activityFilteringForETWEnabled[i] ensures we
                    //  do not fire events indiscriminately, when no filters are specified, but only 
                    //  if, in addition, the session did not also enable ActivitySampling)
                    if (activityFilter == null && !m_activityFilteringForETWEnabled[i] || 
                        activityFilter != null && 
                            ActivityFilter.PassesActivityFilter(activityFilter, childActivityID, 
                                m_eventData[eventId].TriggersActivityTracking > 0, this, eventId) ||
                        !m_activityFilteringForETWEnabled[i])
                    {
                        etwSessions[i] = true;
                    }
                }
            }
            // flow "interesting" activities for all legacy sessions in which there's some 
            // level of activity tracing enabled (even other EventSources)
            if (m_legacySessions != null && m_legacySessions.Count > 0 && 
                (EventOpcode)m_eventData[eventId].Descriptor.Opcode == EventOpcode.Send)
            {
                // only calculate InternalCurrentThreadActivityId once
                Guid *pCurrentActivityId = null;
                Guid currentActivityId;
                foreach (var legacyEtwSession in m_legacySessions)
                {
                    if (legacyEtwSession == null)
                        continue;

                    ActivityFilter activityFilter = legacyEtwSession.m_activityFilter;
                    if (activityFilter != null)
                    {
                        if (pCurrentActivityId == null)
                        {
                            currentActivityId = InternalCurrentThreadActivityId;
                            pCurrentActivityId = &currentActivityId;
                        }
                        ActivityFilter.FlowActivityIfNeeded(activityFilter, pCurrentActivityId, childActivityID);
                    }
                }
            }

            return etwSessions;
        }
 // Token: 0x0600343F RID: 13375 RVA: 0x000CA56F File Offset: 0x000C876F
 public SessionMask(SessionMask m)
 {
     this.m_mask = m.m_mask;
 }
 // Token: 0x06003441 RID: 13377 RVA: 0x000CA589 File Offset: 0x000C8789
 public bool IsEqualOrSupersetOf(SessionMask m)
 {
     return((this.m_mask | m.m_mask) == this.m_mask);
 }