private void UpdateStartStopActivityOnAwaitComplete(TraceActivity activity, TraceEvent data) { // If we are createing 'UNKNOWN_ASYNC nodes, make sure that AWAIT_TIME does not overlap with UNKNOWN_ASYNC time var startStopActivity = m_startStopActivities.GetStartStopActivityForActivity(activity); if (startStopActivity == null) { return; } while (startStopActivity.Creator != null) { startStopActivity = startStopActivity.Creator; } // If the await finishes before the ASYNC_UNKNOWN, simply adust the time. if (0 <= m_unknownTimeStartMsec.Get((int)startStopActivity.Index)) { m_unknownTimeStartMsec.Set((int)startStopActivity.Index, data.TimeStampRelativeMSec); } // It is possible that the ASYNC_UNKOWN has already completed. In that case, remove overlapping ones List <StackSourceSample> async_unknownSamples = m_startStopActivityToAsyncUnknownSamples.Get((int)startStopActivity.Index); if (async_unknownSamples != null) { int removeStart = async_unknownSamples.Count; while (0 < removeStart) { int probe = removeStart - 1; var sample = async_unknownSamples[probe]; if (activity.CreationTimeRelativeMSec <= sample.TimeRelativeMSec + sample.Metric) // There is overlap { removeStart = probe; } else { break; } } int removeCount = async_unknownSamples.Count - removeStart; if (removeCount > 0) { async_unknownSamples.RemoveRange(removeStart, removeCount); } } }
// THis is for the TaskWaitEnd. We want to have a stack event if 'data' does not have one, we lose the fact that // ANYTHING happened on this thread. Thus we log the stack of the activity so that data does not need a stack. private void OnTaskUnblock(TraceEvent data) { if (m_activityComputer == null) { return; } TraceThread thread = data.Thread(); if (thread != null) { TraceActivity activity = m_activityComputer.GetCurrentActivity(thread); StackSourceCallStackIndex stackIndex = m_activityComputer.GetCallStackForActivity(m_outputStackSource, activity, GetTopFramesForActivityComputerCase(data, data.Thread())); m_threadState[(int)thread.ThreadIndex].LogThreadStack(data.TimeStampRelativeMSec, stackIndex, thread, this, onCPU: true); } else { Debug.WriteLine("Warning, no thread at " + data.TimeStampRelativeMSec.ToString("f3")); } }
private void TraceViaSource() { using (var trace = TraceActivity.Create("Tracing via source")) { var dt = DateTime.Now; trace.Verbose(1001, "This is a verbose message sent via source " + dt); trace.Information(1002, "This is an informational message sent via source " + dt); trace.Warning(1003, "This is a warning message sent via source " + dt); trace.Error(1004, "This is an error message sent via source " + dt); trace.Critical(1005, "This is a critical message sent via source " + dt); try { throw new DivideByZeroException("Test exception 1"); } catch (Exception e) { trace.Warning(1006, e, "This is a warning message with exception sent via source " + dt); } try { throw new ArgumentException("Test exception 2"); } catch (Exception e) { trace.Error(1004, e, "This is an error message sent via source " + dt); } try { throw new ArgumentNullException("Test exception 3"); } catch (Exception e) { trace.Critical(1005, e, "This is a critical message sent via source " + dt); } } }
internal ETWEventRecord(ETWEventSource source, TraceEvent data, Dictionary <string, int> columnOrder, int nonRestFields, double durationMSec) : base(nonRestFields) { m_source = source; m_name = data.ProviderName + "/" + data.EventName; m_processName = data.ProcessName; if (!m_processName.StartsWith("(")) { m_processName += " (" + data.ProcessID + ")"; } m_timeStampRelativeMSec = data.TimeStampRelativeMSec; m_idx = data.EventIndex; // Compute the data column var restString = new StringBuilder(); // Deal with the special HasStack, ThreadID and ActivityID, DataLength fields; var hasStack = data.CallStackIndex() != CallStackIndex.Invalid; if (hasStack) { AddField("HasStack", hasStack.ToString(), columnOrder, restString); } var asCSwitch = data as CSwitchTraceData; if (asCSwitch != null) { AddField("HasBlockingStack", (asCSwitch.BlockingStack() != CallStackIndex.Invalid).ToString(), columnOrder, restString); } AddField("ThreadID", data.ThreadID.ToString("n0"), columnOrder, restString); AddField("ProcessorNumber", data.ProcessorNumber.ToString(), columnOrder, restString); if (0 < durationMSec) { AddField("DURATION_MSEC", durationMSec.ToString("n3"), columnOrder, restString); } var payloadNames = data.PayloadNames; if (payloadNames.Length == 0 && data.EventDataLength != 0) { // WPP events look classic and use the EventID as their discriminator if (data.IsClassicProvider && data.ID != 0) { AddField("EventID", ((int)data.ID).ToString(), columnOrder, restString); } AddField("DataLength", data.EventDataLength.ToString(), columnOrder, restString); } try { for (int i = 0; i < payloadNames.Length; i++) { AddField(payloadNames[i], data.PayloadString(i), columnOrder, restString); } } catch (Exception e) { AddField("ErrorParsingFields", e.Message, columnOrder, restString); } var message = data.FormattedMessage; if (message != null) { AddField("FormattedMessage", message, columnOrder, restString); } if (source.m_needsComputers) { TraceThread thread = data.Thread(); if (thread != null) { TraceActivity activity = source.m_activityComputer.GetCurrentActivity(thread); if (activity != null) { string id = activity.ID; if (Math.Abs(activity.StartTimeRelativeMSec - m_timeStampRelativeMSec) < .0005) { id = "^" + id; // Indicates it is at the start of the task. } AddField("ActivityInfo", id, columnOrder, restString); } var startStopActivity = source.m_startStopActivityComputer.GetCurrentStartStopActivity(thread, data); if (startStopActivity != null) { string name = startStopActivity.Name; string parentName = "$"; if (startStopActivity.Creator != null) { parentName = startStopActivity.Creator.Name; } AddField("StartStopActivity", name + "/P=" + parentName, columnOrder, restString); } } } // We pass 0 as the process ID for creating the activityID because we want uniform syntax. if (data.ActivityID != Guid.Empty) { AddField("ActivityID", StartStopActivityComputer.ActivityPathString(data.ActivityID), columnOrder, restString); } Guid relatedActivityID = data.RelatedActivityID; if (relatedActivityID != Guid.Empty) { AddField("RelatedActivityID", StartStopActivityComputer.ActivityPathString(data.RelatedActivityID), columnOrder, restString); } if (data.ContainerID != null) { AddField("ContainerID", data.ContainerID, columnOrder, restString); } m_asText = restString.ToString(); }