public DbgExceptionImpl(DbgRuntime runtime, DbgExceptionId id, DbgExceptionEventFlags flags, string message, DbgThread thread, DbgModule module) { if (id.IsDefaultId) { throw new ArgumentException(); } Runtime = runtime ?? throw new ArgumentNullException(nameof(runtime)); Id = id; Flags = flags; Message = message; Thread = thread; Module = module; }
/// <summary> /// Constructor /// </summary> /// <param name="id">Exception id</param> /// <param name="settings">Settings</param> public DbgExceptionIdAndSettings(DbgExceptionId id, DbgExceptionSettings settings) { if (id.Category == null) { throw new ArgumentException(); } if (settings.Conditions == null) { throw new ArgumentException(); } Id = id; Settings = settings; }
public override DbgException CreateException <T>(DbgExceptionId id, DbgExceptionEventFlags flags, string message, DbgThread thread, DbgModule module, DbgEngineMessageFlags messageFlags, T data, Action <DbgException> onCreated) { if (id.IsDefaultId) { throw new ArgumentException(); } var exception = new DbgExceptionImpl(runtime, id, flags, message, thread, module); if (data != null) { exception.GetOrCreateData(() => data); } onCreated?.Invoke(exception); owner.Dispatcher.BeginInvoke(() => owner.AddException_DbgThread(runtime, exception, messageFlags)); return(exception); }
public override bool TryGetSettings(DbgExceptionId id, out DbgExceptionSettings settings) { if (id.Category is null) { throw new ArgumentException(); } lock (lockObj) { if (toExceptionInfo.TryGetValue(id, out var info)) { settings = info.Settings; return(true); } } settings = default; return(false); }
public override bool TryGetDefinition(DbgExceptionId id, out DbgExceptionDefinition definition) { if (id.Category is null) { throw new ArgumentException(); } lock (lockObj) { if (toExceptionInfo.TryGetValue(id, out var info)) { definition = info.Definition; return(true); } } definition = default; return(false); }
public override DbgExceptionSettings GetSettings(DbgExceptionId id) { if (id.Category is null) { throw new ArgumentException(); } lock (lockObj) { if (toExceptionInfo.TryGetValue(id, out var info)) { return(info.Settings); } if (toExceptionInfo.TryGetValue(new DbgExceptionId(id.Category), out info)) { return(info.Settings); } } return(new DbgExceptionSettings(DbgExceptionDefinitionFlags.None)); }
public override void Execute(string context) { if (context == null) { return; } var id = new DbgExceptionId(PredefinedExceptionCategories.DotNet, context); if (dbgExceptionSettingsService.Value.TryGetSettings(id, out var settings)) { settings = new DbgExceptionSettings(settings.Flags | DbgExceptionDefinitionFlags.StopFirstChance, settings.Conditions); dbgExceptionSettingsService.Value.Modify(id, settings); } else { var def = new DbgExceptionDefinition(id, DbgExceptionDefinitionFlags.StopFirstChance | DbgExceptionDefinitionFlags.StopSecondChance); settings = new DbgExceptionSettings(def.Flags); var info = new DbgExceptionSettingsInfo(def, settings); dbgExceptionSettingsService.Value.Add(info); } }
void Load() { dbgDispatcherProvider.VerifyAccess(); ignoreSave = true; dbgExceptionSettingsService.Reset(); var section = settingsService.GetOrCreateSection(SETTINGS_GUID); var exToAdd = new List <DbgExceptionSettingsInfo>(); var exToRemove = new List <DbgExceptionId>(); var exToUpdate = new List <DbgExceptionIdAndSettings>(); foreach (var categorySect in section.SectionsWithName("Category")) { var category = categorySect.Attribute <string>("Name"); if (string.IsNullOrEmpty(category)) { continue; } foreach (var exSect in categorySect.SectionsWithName("Exception")) { var diffType = exSect.Attribute <DiffType?>("DiffType"); if (diffType == null) { continue; } var idKind = exSect.Attribute <DbgExceptionIdKind?>("IdKind"); if (idKind == null) { continue; } DbgExceptionId id; switch (idKind.Value) { case DbgExceptionIdKind.DefaultId: id = new DbgExceptionId(category); break; case DbgExceptionIdKind.Code: var code = exSect.Attribute <int?>("Code"); if (code == null) { continue; } id = new DbgExceptionId(category, code.Value); break; case DbgExceptionIdKind.Name: var name = exSect.Attribute <string>("Name"); if (name == null) { continue; } id = new DbgExceptionId(category, name); break; default: Debug.Fail($"Unknown id kind: {idKind.Value}"); continue; } DbgExceptionSettings settings; switch (diffType.Value) { case DiffType.Add: if (!ReadSettings(exSect, out settings)) { continue; } var description = exSect.Attribute <string>("Description"); exToAdd.Add(new DbgExceptionSettingsInfo(new DbgExceptionDefinition(id, settings.Flags, description), settings)); break; case DiffType.Remove: exToRemove.Add(id); break; case DiffType.Update: if (!ReadSettings(exSect, out settings)) { continue; } exToUpdate.Add(new DbgExceptionIdAndSettings(id, settings)); break; default: Debug.Fail($"Unknown diff type: {diffType}"); break; } } } if (exToRemove.Count > 0) { dbgExceptionSettingsService.Remove(exToRemove.ToArray()); } if (exToAdd.Count > 0) { dbgExceptionSettingsService.Add(exToAdd.ToArray()); } if (exToUpdate.Count > 0) { dbgExceptionSettingsService.Modify(exToUpdate.ToArray()); } dbgDispatcherProvider.Dbg(() => ignoreSave = false); }
/// <summary> /// Creates an exception. The engine has paused the program. /// </summary> /// <typeparam name="T">Type of data</typeparam> /// <param name="id">Exception id</param> /// <param name="flags">Exception event flags</param> /// <param name="message">Exception message or null if it's not available</param> /// <param name="thread">Thread where exception was thrown or null if it's unknown</param> /// <param name="module">Module where exception was thrown or null if it's unknown</param> /// <param name="messageFlags">Message flags</param> /// <param name="data">Data to add to the <see cref="DbgException"/> or null if nothing gets added</param> /// <param name="onCreated">Called right after creating the exception but before adding it to internal data structures. This can be null.</param> /// <returns></returns> public abstract DbgException CreateException <T>(DbgExceptionId id, DbgExceptionEventFlags flags, string message, DbgThread thread, DbgModule module, DbgEngineMessageFlags messageFlags, T data, Action <DbgException> onCreated = null) where T : class;
/// <summary> /// Creates an exception. The engine has paused the program. /// </summary> /// <param name="id">Exception id</param> /// <param name="flags">Exception event flags</param> /// <param name="message">Exception message or null if it's not available</param> /// <param name="thread">Thread where exception was thrown or null if it's unknown</param> /// <param name="module">Module where exception was thrown or null if it's unknown</param> /// <param name="messageFlags">Message flags</param> /// <returns></returns> public DbgException CreateException(DbgExceptionId id, DbgExceptionEventFlags flags, string message, DbgThread thread, DbgModule module, DbgEngineMessageFlags messageFlags) => CreateException <object>(id, flags, message, thread, module, messageFlags, null, null);
public abstract void WriteName(IDbgTextWriter writer, DbgExceptionId id, bool includeDescription);
public void Read(string filename) { try { if (!File.Exists(filename)) { return; } var doc = XDocument.Load(filename, LoadOptions.None); var root = doc.Root; if (root.Name == "Exceptions") { foreach (var categoryDefElem in root.Elements("CategoryDef")) { var name = (string)categoryDefElem.Attribute("Name"); var displayName = (string)categoryDefElem.Attribute("DisplayName"); var shortDisplayName = (string)categoryDefElem.Attribute("ShortDisplayName"); var flagsAttr = (string)categoryDefElem.Attribute("Flags"); if (string.IsNullOrWhiteSpace(name) || string.IsNullOrWhiteSpace(displayName) || string.IsNullOrWhiteSpace(shortDisplayName)) { continue; } var flags = ParseCategoryFlags(flagsAttr); CategoryDefinitions.Add(new DbgExceptionCategoryDefinition(flags, name, displayName, shortDisplayName)); } foreach (var exDefCollElem in root.Elements("ExceptionDefs")) { var category = (string)exDefCollElem.Attribute("Category"); if (string.IsNullOrWhiteSpace(category)) { continue; } foreach (var exDefElem in exDefCollElem.Elements("Exception")) { var name = (string)exDefElem.Attribute("Name"); var code = (string)exDefElem.Attribute("Code"); var description = (string)exDefElem.Attribute("Description"); if (string.IsNullOrWhiteSpace(description)) { description = null; } var flagsAttr = (string)exDefElem.Attribute("Flags"); DbgExceptionId id; if (code == null) { if (string.IsNullOrWhiteSpace(name)) { continue; } id = new DbgExceptionId(category, name); } else { code = code.Trim(); bool isHex = code.StartsWith("0x", StringComparison.OrdinalIgnoreCase) || code.StartsWith("&H", StringComparison.OrdinalIgnoreCase); if (isHex) { code = code.Substring(2); if (code != code.Trim() || code.StartsWith("-") || code.StartsWith("+")) { continue; } if (!int.TryParse(code, NumberStyles.HexNumber, null, out int codeValue)) { if (!uint.TryParse(code, NumberStyles.HexNumber, null, out uint codeValueU)) { continue; } codeValue = (int)codeValueU; } } else { if (!int.TryParse(code, out int codeValue)) { if (!uint.TryParse(code, out uint codeValueU)) { continue; } codeValue = (int)codeValueU; } } id = new DbgExceptionId(category, code); } ExceptionDefinitions.Add(new DbgExceptionDefinition(id, ParseExceptionFlags(flagsAttr), description)); } } } } catch { } }
DefaultExceptionDefinitionsProvider([ImportMany] IEnumerable <Lazy <DbgExceptionDefinitionProvider, IDbgExceptionDefinitionProviderMetadata> > dbgExceptionDefinitionProviders) { var providers = dbgExceptionDefinitionProviders.OrderBy(a => a.Metadata.Order).ToArray(); var xmlFiles = new List <string>(); foreach (var p in providers) { foreach (var file in p.Value.GetExceptionFilenames()) { string filename; if (Path.IsPathRooted(file)) { filename = file; } else { filename = Path.Combine(Path.GetDirectoryName(p.Value.GetType().Assembly.Location), file); } if (!File.Exists(filename)) { continue; } xmlFiles.Add(filename); } } var debugDir = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "debug"); xmlFiles.AddRange(Directory.GetFiles(debugDir, "*.ex.xml").OrderBy(a => a, StringComparer.OrdinalIgnoreCase)); var reader = new ExceptionsFileReader(); foreach (var file in xmlFiles.Distinct(StringComparer.OrdinalIgnoreCase)) { reader.Read(file); } var categoryDefs = new Dictionary <string, DbgExceptionCategoryDefinition>(StringComparer.Ordinal); foreach (var p in providers) { foreach (var def in p.Value.CreateCategories()) { if (!categoryDefs.ContainsKey(def.Name)) { categoryDefs.Add(def.Name, def); } } } // Categories from files have lower priority than anything from CreateCategories() foreach (var def in reader.CategoryDefinitions) { if (!categoryDefs.ContainsKey(def.Name)) { categoryDefs.Add(def.Name, def); } } CategoryDefinitions = new ReadOnlyCollection <DbgExceptionCategoryDefinition>(categoryDefs.Select(a => a.Value).ToArray()); var defs = new Dictionary <DbgExceptionId, DbgExceptionDefinition>(); foreach (var p in providers) { foreach (var def in p.Value.Create()) { bool b = categoryDefs.ContainsKey(def.Id.Category); Debug.Assert(b); if (!b) { continue; } if (!defs.ContainsKey(def.Id)) { defs.Add(def.Id, def); } } } // Exceptions from files have lower priority than anything from Create() foreach (var def in reader.ExceptionDefinitions) { bool b = categoryDefs.ContainsKey(def.Id.Category); Debug.Assert(b); if (!b) { continue; } if (!defs.ContainsKey(def.Id)) { defs.Add(def.Id, def); } } foreach (var category in CategoryDefinitions) { var id = new DbgExceptionId(category.Name); if (!defs.ContainsKey(id)) { defs.Add(id, new DbgExceptionDefinition(id, DbgExceptionDefinitionFlags.None)); } } Definitions = new ReadOnlyCollection <DbgExceptionDefinition>(defs.Select(a => a.Value).ToArray()); }