protected unsafe void WriteEventWithRelatedActivityIdCore(int eventId, Guid* childActivityID, int eventDataCount, EventSource.EventData* data) { if (m_eventSourceEnabled) { Contract.Assert(m_eventData != null); // You must have initialized this if you enabled the source. if (childActivityID != null) ValidateEventOpcodeForTransfer(ref m_eventData[eventId]); #if FEATURE_MANAGED_ETW if (m_eventData[eventId].EnabledForETW) { #if FEATURE_ACTIVITYSAMPLING // this code should be kept in [....] with WriteEventVarargs(). SessionMask etwSessions = SessionMask.All; // only compute etwSessions if there are *any* ETW filters enabled... if ((ulong)m_curLiveSessions != 0) etwSessions = GetEtwSessionMask(eventId, childActivityID); // OutputDebugString(string.Format("{0}.WriteEvent(id {1}) -> to sessions {2:x}", // m_name, m_eventData[eventId].Name, (ulong) etwSessions)); if ((ulong)etwSessions != 0 || m_legacySessions != null && m_legacySessions.Count > 0) { if (etwSessions.IsEqualOrSupersetOf(m_curLiveSessions)) { // OutputDebugString(string.Format(" (1) id {0}, kwd {1:x}", // m_eventData[eventId].Name, m_eventData[eventId].Descriptor.Keywords)); // by default the Descriptor.Keyword will have the perEventSourceSessionId bit // mask set to 0x0f so, when all ETW sessions want the event we don't need to // synthesize a new one if (!m_provider.WriteEvent(ref m_eventData[eventId].Descriptor, childActivityID, eventDataCount, (IntPtr)data)) ThrowEventSourceException(); } else { long origKwd = (long)((ulong) m_eventData[eventId].Descriptor.Keywords & ~(SessionMask.All.ToEventKeywords())); // OutputDebugString(string.Format(" (2) id {0}, kwd {1:x}", // m_eventData[eventId].Name, etwSessions.ToEventKeywords() | (ulong) origKwd)); // only some of the ETW sessions will receive this event. Synthesize a new // Descriptor whose Keywords field will have the appropriate bits set. // etwSessions might be 0, if there are legacy ETW listeners that want this event var desc = new System.Diagnostics.Tracing.EventDescriptor( m_eventData[eventId].Descriptor.EventId, m_eventData[eventId].Descriptor.Version, m_eventData[eventId].Descriptor.Channel, m_eventData[eventId].Descriptor.Level, m_eventData[eventId].Descriptor.Opcode, m_eventData[eventId].Descriptor.Task, (long) etwSessions.ToEventKeywords() | origKwd); if (!m_provider.WriteEvent(ref desc, childActivityID, eventDataCount, (IntPtr)data)) ThrowEventSourceException(); } } #else if (!m_provider.WriteEvent(ref m_eventData[eventId].Descriptor, childActivityID, eventDataCount, (IntPtr)data)) ThrowEventSourceException(); #endif // FEATURE_ACTIVITYSAMPLING } #endif if (m_Dispatchers != null && m_eventData[eventId].EnabledForAnyListener) WriteToAllListeners(eventId, childActivityID, eventDataCount, data); } }
private unsafe bool SendManifest(byte[] rawManifest) { bool success = true; #if FEATURE_MANAGED_ETW fixed (byte* dataPtr = rawManifest) { var manifestDescr = new System.Diagnostics.Tracing.EventDescriptor(0xFFFE, 1, 0, 0, 0xFE, 0xFFFE, -1); ManifestEnvelope envelope = new ManifestEnvelope(); envelope.Format = ManifestEnvelope.ManifestFormats.SimpleXmlFormat; envelope.MajorVersion = 1; envelope.MinorVersion = 0; envelope.Magic = 0x5B; // An unusual number that can be checked for consistancy. int dataLeft = rawManifest.Length; envelope.TotalChunks = (ushort)((dataLeft + (ManifestEnvelope.MaxChunkSize - 1)) / ManifestEnvelope.MaxChunkSize); envelope.ChunkNumber = 0; EventProvider.EventData* dataDescrs = stackalloc EventProvider.EventData[2]; dataDescrs[0].Ptr = (ulong)&envelope; dataDescrs[0].Size = (uint)sizeof(ManifestEnvelope); dataDescrs[0].Reserved = 0; dataDescrs[1].Ptr = (ulong)dataPtr; dataDescrs[1].Reserved = 0; int chunkSize = ManifestEnvelope.MaxChunkSize; TRY_AGAIN_WITH_SMALLER_CHUNK_SIZE: while (dataLeft > 0) { dataDescrs[1].Size = (uint)Math.Min(dataLeft, chunkSize); if (m_provider != null) { if (!m_provider.WriteEvent(ref manifestDescr, null, 2, (IntPtr)dataDescrs)) { // Turns out that if users set the BufferSize to something less than 64K then WriteEvent // can fail. If we get this failure on the first chunk try again with something smaller // The smallest BufferSize is 1K so if we get to 512, we can give up making it smaller. if (EventProvider.GetLastWriteEventError() == EventProvider.WriteEventErrorCode.EventTooBig) { chunkSize = chunkSize / 2; if (envelope.ChunkNumber == 0 && chunkSize > 512) goto TRY_AGAIN_WITH_SMALLER_CHUNK_SIZE; } success = false; if(m_throwOnEventWriteErrors) ThrowEventSourceException(); } } dataLeft -= ManifestEnvelope.MaxChunkSize; dataDescrs[1].Ptr += ManifestEnvelope.MaxChunkSize; envelope.ChunkNumber++; } } #endif return success; }