internal void AddProviderEvents(ITraceParserServices source, Action<TraceEvent> callback) { if (Error != null) return; if (!inited) Init(); try { Dictionary<string, int> opcodes = new Dictionary<string, int>(); opcodes.Add("win:Info", 0); opcodes.Add("win:Start", 1); opcodes.Add("win:Stop", 2); opcodes.Add("win:DC_Start", 3); opcodes.Add("win:DC_Stop", 4); opcodes.Add("win:Extension", 5); opcodes.Add("win:Reply", 6); opcodes.Add("win:Resume", 7); opcodes.Add("win:Suspend", 8); opcodes.Add("win:Send", 9); opcodes.Add("win:Receive", 240); Dictionary<string, TaskInfo> tasks = new Dictionary<string, TaskInfo>(); Dictionary<string, TemplateInfo> templates = new Dictionary<string, TemplateInfo>(); Dictionary<string, IDictionary<long, string>> maps = null; Dictionary<string, string> strings = new Dictionary<string, string>(); IDictionary<long, string> map = null; List<EventInfo> events = new List<EventInfo>(); bool alreadyReadMyCulture = false; // I read my culture some time in the past (I can igore things) string cultureBeingRead = null; while (reader.Read()) { // TODO I currently require opcodes,and tasks BEFORE events BEFORE templates. // Can be fixed by going multi-pass. switch (reader.Name) { case "event": { int taskNum = 0; Guid taskGuid = Guid; string taskName = reader.GetAttribute("task"); if (taskName != null) { TaskInfo taskInfo; if (tasks.TryGetValue(taskName, out taskInfo)) { taskNum = taskInfo.id; taskGuid = taskInfo.guid; } } else taskName = ""; int eventID = int.Parse(reader.GetAttribute("value")); int opcode = 0; string opcodeName = reader.GetAttribute("opcode"); if (opcodeName != null) { opcodes.TryGetValue(opcodeName, out opcode); // Strip off any namespace prefix. TODO is this a good idea? int colon = opcodeName.IndexOf(':'); if (colon >= 0) opcodeName = opcodeName.Substring(colon + 1); } else { opcodeName = ""; // opcodeName = "UnknownEvent" + eventID.ToString(); } DynamicTraceEventData eventTemplate = new DynamicTraceEventData( callback, eventID, taskNum, taskName, taskGuid, opcode, opcodeName, Guid, Name); events.Add(new EventInfo(eventTemplate, reader.GetAttribute("template"))); // This will be looked up in the string table in a second pass. eventTemplate.MessageFormat = reader.GetAttribute("message"); } break; case "template": { string templateName = reader.GetAttribute("tid"); Debug.Assert(templateName != null); #if DEBUG try { #endif templates.Add(templateName, ComputeFieldInfo(reader.ReadSubtree(), maps)); #if DEBUG } catch (Exception e) { Console.WriteLine("Error: Exception during processing template {0}: {1}", templateName, e.ToString()); throw; } #endif } break; case "opcode": // TODO use message for opcode if it is available so it is localized. opcodes.Add(reader.GetAttribute("name"), int.Parse(reader.GetAttribute("value"))); break; case "task": { TaskInfo info = new TaskInfo(); info.id = int.Parse(reader.GetAttribute("value")); string guidString = reader.GetAttribute("eventGUID"); if (guidString != null) info.guid = new Guid(guidString); tasks.Add(reader.GetAttribute("name"), info); } break; case "valueMap": map = new Dictionary<long, string>(); // value maps use dictionaries goto DoMap; case "bitMap": map = new SortedList<long, string>(); // Bitmaps stored as sorted lists goto DoMap; DoMap: string name = reader.GetAttribute("name"); var mapValues = reader.ReadSubtree(); while (mapValues.Read()) { if (mapValues.Name == "map") { string keyStr = reader.GetAttribute("value"); long key; if (keyStr.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) key = long.Parse(keyStr.Substring(2), System.Globalization.NumberStyles.AllowHexSpecifier); else key = long.Parse(keyStr); string value = reader.GetAttribute("message"); map[key] = value; } } if (maps == null) maps = new Dictionary<string, IDictionary<long, string>>(); maps[name] = map; break; case "resources": { if (!alreadyReadMyCulture) { string desiredCulture = System.Globalization.CultureInfo.CurrentCulture.Name; if (cultureBeingRead != null && string.Compare(cultureBeingRead, desiredCulture, StringComparison.OrdinalIgnoreCase) == 0) alreadyReadMyCulture = true; cultureBeingRead = reader.GetAttribute("culture"); } } break; case "string": if (!alreadyReadMyCulture) strings[reader.GetAttribute("id")] = reader.GetAttribute("value"); break; } } // localize strings for maps. if (maps != null) { foreach (IDictionary<long, string> amap in maps.Values) { foreach (var keyValue in new List<KeyValuePair<long, string>>(amap)) { Match m = Regex.Match(keyValue.Value, @"^\$\(string\.(.*)\)$"); if (m.Success) { string newValue; if (strings.TryGetValue(m.Groups[1].Value, out newValue)) amap[keyValue.Key] = newValue; } } } } // Register all the events foreach (var eventInfo in events) { var event_ = eventInfo.eventTemplate; // Set the template if there is any. if (eventInfo.templateName != null) { var templateInfo = templates[eventInfo.templateName]; event_.payloadNames = templateInfo.payloadNames.ToArray(); event_.payloadFetches = templateInfo.payloadFetches.ToArray(); } else { event_.payloadNames = new string[0]; event_.payloadFetches = new DynamicTraceEventData.PayloadFetch[0]; } // before registering, localize any message format strings. string message = event_.MessageFormat; if (message != null) { // Expect $(STRINGNAME) where STRINGNAME needs to be looked up in the string table // TODO currently we just ignore messages without a valid string name. Is that OK? event_.MessageFormat = null; Match m = Regex.Match(message, @"^\$\(string\.(.*)\)$"); if (m.Success) strings.TryGetValue(m.Groups[1].Value, out event_.MessageFormat); } //SLAB update try/catch section try { source.RegisterEventTemplate(event_); } catch (NullReferenceException e) { // This error may be thrown when disposing source. Error = e; inited = false; // If we call it again, start over from the begining. return; } } //SLAB comment: // The below code was commented out to allow receiving manifest updates. // Note that this registration will set the manifest event as handled and will always send // the initial manifest (no updates) so this behavior will be useless for manifest caching scenarios // where stale manifest should be avoided by receiving new updates. // To recap, avoiding manifest event registration will force to get unhandled events on each new manifest event. //// Create an event for the manifest event itself so it looks pretty in dumps. //source.RegisterEventTemplate(new DynamicManifestTraceEventData(callback, this)); } catch (Exception e) { // TODO FIX NOW, log this! Debug.Assert(false, "Exception during manifest parsing"); #if DEBUG Console.WriteLine("Error: Exception during processing of in-log manifest for provider {0}. Symbolic information may not be complete.", Name); #endif Error = e; } inited = false; // If we call it again, start over from the begining. }
public void AddProviderEvents(ITraceParserServices source, Action<TraceEvent> callback) { if (error != null) return; if (!inited) Init(); try { Dictionary<string, int> opcodes = new Dictionary<string, int>(); opcodes.Add("win:Info", 0); opcodes.Add("win:Start", 1); opcodes.Add("win:Stop", 2); opcodes.Add("win:DC_Start", 3); opcodes.Add("win:DC_End", 4); opcodes.Add("win:Extension", 5); opcodes.Add("win:Reply", 6); opcodes.Add("win:Resume", 7); opcodes.Add("win:Suspend", 8); opcodes.Add("win:Send", 9); opcodes.Add("win:Receive", 240); Dictionary<string, TaskInfo> tasks = new Dictionary<string, TaskInfo>(); Dictionary<string, DynamicTraceEventData> templates = new Dictionary<string, DynamicTraceEventData>(); while (reader.Read()) { // TODO I currently require opcodes,and tasks BEFORE events BEFORE templates. // Can be fixed by going multi-pass. switch (reader.Name) { case "event": { int taskNum = 0; Guid taskGuid = Guid; string taskName = reader.GetAttribute("task"); if (taskName != null) { TaskInfo taskInfo; if (tasks.TryGetValue(taskName, out taskInfo)) { taskNum = taskInfo.id; taskGuid = taskInfo.guid; } } else taskName = ""; int opcode = 0; string opcodeName = reader.GetAttribute("opcode"); if (opcodeName != null) { opcode = opcodes[opcodeName]; // Strip off any namespace prefix (TODO is this a good idea? int colon = opcodeName.IndexOf(':'); if (colon >= 0) opcodeName = opcodeName.Substring(colon + 1); } else { // TODO: Improve this. // If we don't have an opcode (which is bad, since it does not work on XP), opcodeName = reader.GetAttribute("name"); if (taskName != null && opcodeName.StartsWith(taskName)) opcodeName = opcodeName.Substring(taskName.Length); } int eventID = int.Parse(reader.GetAttribute("value")); DynamicTraceEventData eventTemplate = new DynamicTraceEventData( callback, eventID, taskNum, taskName, taskGuid, opcode, opcodeName, Guid, Name); string templateName = reader.GetAttribute("template"); if (templateName != null) templates[templateName] = eventTemplate; else { eventTemplate.payloadNames = new string[0]; eventTemplate.payloadFetches = new DynamicTraceEventData.PayloadFetch[0]; source.RegisterEventTemplate(eventTemplate); } } break; case "template": { string templateName = reader.GetAttribute("tid"); Debug.Assert(templateName != null); DynamicTraceEventData eventTemplate = templates[templateName]; try { ComputeFieldInfo(eventTemplate, reader.ReadSubtree()); } catch (Exception e) { Console.WriteLine("Error: Exception during processing template {0}: {1}", templateName, e.ToString()); throw; } source.RegisterEventTemplate(eventTemplate); templates.Remove(templateName); } break; case "opcode": opcodes.Add(reader.GetAttribute("name"), int.Parse(reader.GetAttribute("value"))); break; case "task": { TaskInfo info = new TaskInfo(); info.id = int.Parse(reader.GetAttribute("value")); string guidString = reader.GetAttribute("eventGUID"); if (guidString != null) info.guid = new Guid(guidString); tasks.Add(reader.GetAttribute("name"), info); } break; } } // TODO Register any events with undefined templates as having empty payloads (can rip out after 1/2009) foreach (DynamicTraceEventData eventTemplate in templates.Values) { eventTemplate.payloadNames = new string[0]; eventTemplate.payloadFetches = new DynamicTraceEventData.PayloadFetch[0]; source.RegisterEventTemplate(eventTemplate); } } catch (Exception e) { Debug.Assert(false, "Exception during manifest parsing"); Console.WriteLine("Error: Exception during processing of in-log manifest for provider {0}. Symbolic information may not be complete.", Name); error = e; } inited = false; // If we call it again, start over from the begining. }
public void AddProviderEvents(ITraceParserServices source, Action <TraceEvent> callback) { if (error != null) { return; } if (!inited) { Init(); } try { Dictionary <string, int> opcodes = new Dictionary <string, int>(); opcodes.Add("win:Info", 0); opcodes.Add("win:Start", 1); opcodes.Add("win:Stop", 2); opcodes.Add("win:DC_Start", 3); opcodes.Add("win:DC_End", 4); opcodes.Add("win:Extension", 5); opcodes.Add("win:Reply", 6); opcodes.Add("win:Resume", 7); opcodes.Add("win:Suspend", 8); opcodes.Add("win:Send", 9); opcodes.Add("win:Receive", 240); Dictionary <string, TaskInfo> tasks = new Dictionary <string, TaskInfo>(); Dictionary <string, DynamicTraceEventData> templates = new Dictionary <string, DynamicTraceEventData>(); while (reader.Read()) { switch (reader.Name) { case "event": { int taskNum = 0; Guid taskGuid = Guid; string taskName = reader.GetAttribute("task"); if (taskName != null) { TaskInfo taskInfo; if (tasks.TryGetValue(taskName, out taskInfo)) { taskNum = taskInfo.id; taskGuid = taskInfo.guid; } } else { taskName = ""; } int opcode = 0; string opcodeName = reader.GetAttribute("opcode"); if (opcodeName != null) { opcode = opcodes[opcodeName]; // Strip off any namespace prefix int colon = opcodeName.IndexOf(':'); if (colon >= 0) { opcodeName = opcodeName.Substring(colon + 1); } } int eventID = int.Parse(reader.GetAttribute("value")); DynamicTraceEventData eventTemplate = new DynamicTraceEventData( callback, eventID, taskNum, taskName, taskGuid, opcode, opcodeName, Guid, Name); string templateName = reader.GetAttribute("template"); if (templateName != null) { templates[templateName] = eventTemplate; } else { eventTemplate.payloadNames = new string[0]; eventTemplate.payloadFetches = new DynamicTraceEventData.PayloadFetch[0]; source.RegisterEventTemplate(eventTemplate); } } break; case "template": { string templateName = reader.GetAttribute("tid"); Debug.Assert(templateName != null); DynamicTraceEventData eventTemplate = templates[templateName]; ComputeFieldInfo(eventTemplate, reader.ReadSubtree()); source.RegisterEventTemplate(eventTemplate); templates.Remove(templateName); } break; case "opcode": opcodes.Add(reader.GetAttribute("name"), int.Parse(reader.GetAttribute("value"))); break; case "task": { TaskInfo info = new TaskInfo(); info.id = int.Parse(reader.GetAttribute("value")); string guidString = reader.GetAttribute("eventGUID"); if (guidString != null) { info.guid = new Guid(guidString); } tasks.Add(reader.GetAttribute("name"), info); } break; } } foreach (DynamicTraceEventData eventTemplate in templates.Values) { eventTemplate.payloadNames = new string[0]; eventTemplate.payloadFetches = new DynamicTraceEventData.PayloadFetch[0]; source.RegisterEventTemplate(eventTemplate); } } catch (Exception e) { Debug.Assert(false, "Exception during manifest parsing"); Console.WriteLine("Error: Exception during processing, symbolic information not available"); error = e; } inited = false; // If we call it again, start over from the begining. }