summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Diagnostics/Eventing/EventProvider.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/Diagnostics/Eventing/EventProvider.cs')
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/EventProvider.cs66
1 files changed, 22 insertions, 44 deletions
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/EventProvider.cs b/src/mscorlib/src/System/Diagnostics/Eventing/EventProvider.cs
index 6ea8d98d92..ce0fcb6acb 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/EventProvider.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/EventProvider.cs
@@ -74,7 +74,6 @@ namespace System.Diagnostics.Tracing
private static bool m_setInformationMissing;
- [SecurityCritical]
UnsafeNativeMethods.ManifestEtw.EtwEnableCallback m_etwCallback; // Trace Callback function
private long m_regHandle; // Trace Registration Handle
private byte m_level; // Tracing Level
@@ -128,7 +127,6 @@ namespace System.Diagnostics.Tracing
// <SatisfiesLinkDemand Name="Win32Exception..ctor(System.Int32)" />
// <ReferencesCritical Name="Method: EtwEnableCallBack(Guid&, Int32, Byte, Int64, Int64, Void*, Void*):Void" Ring="1" />
// </SecurityKernel>
- [System.Security.SecurityCritical]
internal unsafe void Register(Guid providerGuid)
{
m_providerId = providerGuid;
@@ -157,7 +155,6 @@ namespace System.Diagnostics.Tracing
// <SecurityKernel Critical="True" TreatAsSafe="Does not expose critical resource" Ring="1">
// <ReferencesCritical Name="Method: Deregister():Void" Ring="1" />
// </SecurityKernel>
- [System.Security.SecuritySafeCritical]
protected virtual void Dispose(bool disposing)
{
//
@@ -175,16 +172,31 @@ namespace System.Diagnostics.Tracing
// Disable the provider.
m_enabled = false;
- // Do most of the work under a lock to avoid shutdown race.
+ // Do most of the work under a lock to avoid shutdown race.
+
+ long registrationHandle = 0;
lock (EventListener.EventListenersLock)
{
// Double check
if (m_disposed)
return;
- Deregister();
+ registrationHandle = m_regHandle;
+ m_regHandle = 0;
m_disposed = true;
}
+
+ // We do the Unregistration outside the EventListenerLock because there is a lock
+ // inside the ETW routines. This lock is taken before ETW issues commands
+ // Thus the ETW lock gets taken first and then our EventListenersLock gets taken
+ // in SendCommand(), and also here. If we called EventUnregister after taking
+ // the EventListenersLock then the take-lock order is reversed and we can have
+ // deadlocks in race conditions (dispose racing with an ETW command).
+ //
+ // We solve by Unregistering after releasing the EventListenerLock.
+ if (registrationHandle != 0)
+ EventUnregister(registrationHandle);
+
}
/// <summary>
@@ -201,33 +213,10 @@ namespace System.Diagnostics.Tracing
Dispose(false);
}
- /// <summary>
- /// This method un-registers from ETW.
- /// </summary>
- // <SecurityKernel Critical="True" Ring="0">
- // <CallsSuppressUnmanagedCode Name="UnsafeNativeMethods.ManifestEtw.EventUnregister(System.Int64):System.Int32" />
- // </SecurityKernel>
- // TODO Check return code from UnsafeNativeMethods.ManifestEtw.EventUnregister
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "Microsoft.Win32.UnsafeNativeMethods.ManifestEtw.EventUnregister(System.Int64)"), System.Security.SecurityCritical]
- private unsafe void Deregister()
- {
- //
- // Unregister from ETW using the RegHandle saved from
- // the register call.
- //
-
- if (m_regHandle != 0)
- {
- EventUnregister();
- m_regHandle = 0;
- }
- }
-
// <SecurityKernel Critical="True" Ring="0">
// <UsesUnsafeCode Name="Parameter filterData of type: Void*" />
// <UsesUnsafeCode Name="Parameter callbackContext of type: Void*" />
// </SecurityKernel>
- [System.Security.SecurityCritical]
unsafe void EtwEnableCallBack(
[In] ref System.Guid sourceId,
[In] int controlCode,
@@ -348,7 +337,6 @@ namespace System.Diagnostics.Tracing
/// ETW session that was added or remove, and the bool specifies whether the
/// session was added or whether it was removed from the set.
/// </summary>
- [System.Security.SecuritySafeCritical]
private List<Tuple<SessionInfo, bool>> GetSessions()
{
List<SessionInfo> liveSessionList = null;
@@ -424,7 +412,6 @@ namespace System.Diagnostics.Tracing
/// for the current process ID, calling 'action' for each session, and passing it the
/// ETW session and the 'AllKeywords' the session enabled for the current provider.
/// </summary>
- [System.Security.SecurityCritical]
private unsafe void GetSessionInfo(Action<int, long> action)
{
// We wish the EventSource package to be legal for Windows Store applications.
@@ -470,7 +457,7 @@ namespace System.Diagnostics.Tracing
}
if (providerInstance->NextOffset == 0)
break;
- Contract.Assert(0 <= providerInstance->NextOffset && providerInstance->NextOffset < buffSize);
+ Debug.Assert(0 <= providerInstance->NextOffset && providerInstance->NextOffset < buffSize);
var structBase = (byte*)providerInstance;
providerInstance = (UnsafeNativeMethods.ManifestEtw.TRACE_PROVIDER_INSTANCE_INFO*)&structBase[providerInstance->NextOffset];
}
@@ -552,7 +539,6 @@ namespace System.Diagnostics.Tracing
/// returns an array of bytes representing the data, the index into that byte array where the data
/// starts, and the command being issued associated with that data.
/// </summary>
- [System.Security.SecurityCritical]
private unsafe bool GetDataFromController(int etwSessionId,
UnsafeNativeMethods.ManifestEtw.EVENT_FILTER_DESCRIPTOR* filterData, out ControllerCommand command, out byte[] data, out int dataStart)
{
@@ -685,7 +671,6 @@ namespace System.Diagnostics.Tracing
// <UsesUnsafeCode Name="Parameter dataDescriptor of type: EventData*" />
// <UsesUnsafeCode Name="Parameter dataBuffer of type: Byte*" />
// </SecurityKernel>
- [System.Security.SecurityCritical]
private static unsafe object EncodeObject(ref object data, ref EventData* dataDescriptor, ref byte* dataBuffer, ref uint totalEventSize)
/*++
@@ -934,7 +919,6 @@ namespace System.Diagnostics.Tracing
// </SecurityKernel>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Performance-critical code")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")]
- [System.Security.SecurityCritical]
internal unsafe bool WriteEvent(ref EventDescriptor eventDescriptor, Guid* activityID, Guid* childActivityID, params object[] eventPayload)
{
int status = 0;
@@ -1131,13 +1115,12 @@ namespace System.Diagnostics.Tracing
// <CallsSuppressUnmanagedCode Name="UnsafeNativeMethods.ManifestEtw.EventWrite(System.Int64,EventDescriptor&,System.UInt32,System.Void*):System.UInt32" />
// </SecurityKernel>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")]
- [System.Security.SecurityCritical]
internal unsafe protected bool WriteEvent(ref EventDescriptor eventDescriptor, Guid* activityID, Guid* childActivityID, int dataCount, IntPtr data)
{
if (childActivityID != null)
{
// activity transfers are supported only for events that specify the Send or Receive opcode
- Contract.Assert((EventOpcode)eventDescriptor.Opcode == EventOpcode.Send ||
+ Debug.Assert((EventOpcode)eventDescriptor.Opcode == EventOpcode.Send ||
(EventOpcode)eventDescriptor.Opcode == EventOpcode.Receive ||
(EventOpcode)eventDescriptor.Opcode == EventOpcode.Start ||
(EventOpcode)eventDescriptor.Opcode == EventOpcode.Stop);
@@ -1154,7 +1137,6 @@ namespace System.Diagnostics.Tracing
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")]
- [System.Security.SecurityCritical]
internal unsafe bool WriteEventRaw(
ref EventDescriptor eventDescriptor,
Guid* activityID,
@@ -1183,7 +1165,6 @@ namespace System.Diagnostics.Tracing
// These are look-alikes to the Manifest based ETW OS APIs that have been shimmed to work
// either with Manifest ETW or Classic ETW (if Manifest based ETW is not available).
- [SecurityCritical]
private unsafe uint EventRegister(ref Guid providerId, UnsafeNativeMethods.ManifestEtw.EtwEnableCallback enableCallback)
{
m_providerId = providerId;
@@ -1191,12 +1172,9 @@ namespace System.Diagnostics.Tracing
return UnsafeNativeMethods.ManifestEtw.EventRegister(ref providerId, enableCallback, null, ref m_regHandle);
}
- [SecurityCritical]
- private uint EventUnregister()
+ private uint EventUnregister(long registrationHandle)
{
- uint status = UnsafeNativeMethods.ManifestEtw.EventUnregister(m_regHandle);
- m_regHandle = 0;
- return status;
+ return UnsafeNativeMethods.ManifestEtw.EventUnregister(registrationHandle);
}
static int[] nibblebits = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
@@ -1209,7 +1187,7 @@ namespace System.Diagnostics.Tracing
}
private static int bitindex(uint n)
{
- Contract.Assert(bitcount(n) == 1);
+ Debug.Assert(bitcount(n) == 1);
int idx = 0;
while ((n & (1 << idx)) == 0)
idx++;