private bool shouldThrow(string exceptionId, ExceptionBreakMode breakMode) { string[] parts = exceptionId.Split('/'); string category = parts.First(); string name = parts.Last(); ExceptionCategorySettings settings = null; if (!this.exceptionCategorySettings.TryGetValue(category, out settings)) { // No configuration for this category - just send it to the host return(true); } ExceptionBreakMode settingMode = settings.GetExceptionBreakMode(name); if (settingMode == ExceptionBreakMode.Always) { // Host always wants this exeception return(true); } else if (settingMode == ExceptionBreakMode.Unhandled && breakMode == ExceptionBreakMode.Unhandled) { // Host wants this exception if it's unhandled return(true); } else if (settingMode == ExceptionBreakMode.UserUnhandled && (breakMode == ExceptionBreakMode.Unhandled || breakMode == ExceptionBreakMode.UserUnhandled)) { // Host wants this exception if it's not handled by the user return(true); } return(false); }
private static void SetCategory(ExceptionCategorySettings categorySettings, ExceptionBreakpointState newState) { using (var settingsUpdateHolder = categorySettings.GetSettingsUpdate()) { settingsUpdateHolder.Value.NewCategoryState = newState; settingsUpdateHolder.Value.RulesToAdd.Clear(); settingsUpdateHolder.Value.RulesToRemove.Clear(); } }
internal SetExceptionBreakpointsResponse HandleSetExceptionBreakpointsRequest(SetExceptionBreakpointsArguments arguments) { //We assume that we'll only receive exception breakpoints in categories that interest us this.exceptionCategorySettings.Clear(); if (arguments.ExceptionOptions != null) { foreach (ExceptionOptions options in arguments.ExceptionOptions) { // We assume all ExceptionPathSegments will reference a single category string category = options.Path?.FirstOrDefault()?.Names?.FirstOrDefault(); if (String.IsNullOrEmpty(category)) { continue; } ExceptionCategorySettings settings = null; if (!this.exceptionCategorySettings.TryGetValue(category, out settings)) { settings = new ExceptionCategorySettings(category); this.exceptionCategorySettings.Add(category, settings); } ExceptionPathSegment exceptions = options.Path.Skip(1).FirstOrDefault(); if (exceptions != null) { // Set break mode for individual exceptions foreach (string exception in exceptions.Names) { settings.SetExceptionBreakMode(exception, options.BreakMode); } } else { // No path segments beyond the category - set the break mode for the category settings.CategoryBreakMode = options.BreakMode; } } } return(new SetExceptionBreakpointsResponse()); }
private ReadOnlyDictionary <Guid, ExceptionCategorySettings> ReadDefaultSettings(HostConfigurationStore configStore) { Dictionary <Guid, ExceptionCategorySettings> categoryMap = new Dictionary <Guid, ExceptionCategorySettings>(); IEnumerable <Guid> categories = _commandFactory.GetSupportedExceptionCategories(); foreach (Guid categoryId in categories) { string categoryName; HostConfigurationSection categoryConfigSection; configStore.GetExceptionCategorySettings(categoryId, out categoryConfigSection, out categoryName); using (categoryConfigSection) { ExceptionCategorySettings categorySettings = new ExceptionCategorySettings(this, categoryConfigSection, categoryName); categoryMap.Add(categoryId, categorySettings); } } return(new ReadOnlyDictionary <Guid, ExceptionCategorySettings>(categoryMap)); }
private ReadOnlyDictionary <Guid, ExceptionCategorySettings> ReadDefaultSettings(string registryRoot) { Dictionary <Guid, ExceptionCategorySettings> categoryMap = new Dictionary <Guid, ExceptionCategorySettings>(); Lazy <RegistryKey> exceptionKey = new Lazy <RegistryKey>(() => { if (string.IsNullOrEmpty(registryRoot)) { return(null); } return(Registry.LocalMachine.OpenSubKey(registryRoot + @"\AD7Metrics\Exception")); }); try { IEnumerable <Guid> categories = _commandFactory.GetSupportedExceptionCategories(); foreach (Guid categoryId in categories) { using (RegistryKey categoryKey = exceptionKey.Value?.OpenSubKey(categoryId.ToString("B", CultureInfo.InvariantCulture))) { ExceptionCategorySettings categorySettings = new ExceptionCategorySettings(this, categoryKey); categoryMap.Add(categoryId, categorySettings); } } } finally { if (exceptionKey.IsValueCreated && exceptionKey.Value != null) { exceptionKey.Value.Close(); } } return(new ReadOnlyDictionary <Guid, ExceptionCategorySettings>(categoryMap)); }
private ReadOnlyDictionary<Guid, ExceptionCategorySettings> ReadDefaultSettings(string registryRoot) { Dictionary<Guid, ExceptionCategorySettings> categoryMap = new Dictionary<Guid, ExceptionCategorySettings>(); Lazy<RegistryKey> exceptionKey = new Lazy<RegistryKey>(() => { if (string.IsNullOrEmpty(registryRoot)) return null; return Registry.LocalMachine.OpenSubKey(registryRoot + @"\AD7Metrics\Exception"); }); try { IEnumerable<Guid> categories = _commandFactory.GetSupportedExceptionCategories(); foreach (Guid categoryId in categories) { using (RegistryKey categoryKey = exceptionKey.Value?.OpenSubKey(categoryId.ToString("B", CultureInfo.InvariantCulture))) { ExceptionCategorySettings categorySettings = new ExceptionCategorySettings(this, categoryKey); categoryMap.Add(categoryId, categorySettings); } } } finally { if (exceptionKey.IsValueCreated && exceptionKey.Value != null) { exceptionKey.Value.Close(); } } return new ReadOnlyDictionary<Guid, ExceptionCategorySettings>(categoryMap); }
private async Task UpdateCatagory(Guid categoryId, ExceptionCategorySettings categorySettings, SettingsUpdates updates) { // Update the category if (updates.NewCategoryState.HasValue && ( updates.NewCategoryState.Value != ExceptionBreakpointState.None || // send down a rule if the category isn't in the default state categorySettings.CurrentRules.Count != 0)) // Or if we have other rules for the category that we need to blow away { ExceptionBreakpointState newCategoryState = updates.NewCategoryState.Value; categorySettings.CategoryState = newCategoryState; categorySettings.CurrentRules.Clear(); IEnumerable<ulong> breakpointIds = await _commandFactory.SetExceptionBreakpoints(categoryId, null, newCategoryState); if (newCategoryState != ExceptionBreakpointState.None) { ulong breakpointId = breakpointIds.Single(); categorySettings.CurrentRules.Add("*", breakpointId); } } // Process any removes if (updates.RulesToRemove.Count > 0) { // Detach these exceptions from 'CurrentRules' List<ulong> breakpointsToRemove = new List<ulong>(); foreach (string exceptionToRemove in updates.RulesToRemove) { ulong breakpointId; if (!categorySettings.CurrentRules.TryGetValue(exceptionToRemove, out breakpointId)) continue; categorySettings.CurrentRules.Remove(exceptionToRemove); breakpointsToRemove.Add(breakpointId); } if (breakpointsToRemove.Count > 0) { await _commandFactory.RemoveExceptionBreakpoint(categoryId, breakpointsToRemove); } } // process any adds foreach (IGrouping<ExceptionBreakpointState, string> grouping in updates.RulesToAdd.GroupBy((pair) => pair.Value, (pair) => pair.Key)) { IEnumerable<string> exceptionNames = grouping; if (grouping.Key == categorySettings.CategoryState) { // A request to set an exception to the same state as the category is redundant unless we have previously changed the state of that exception to something else exceptionNames = exceptionNames.Intersect(categorySettings.CurrentRules.Keys); if (!exceptionNames.Any()) { continue; // no exceptions left, so ignore this group } } IEnumerable<ulong> breakpointIds = await _commandFactory.SetExceptionBreakpoints(categoryId, exceptionNames, grouping.Key); int count = exceptionNames.Zip(breakpointIds, (exceptionName, breakpointId) => { categorySettings.CurrentRules[exceptionName] = breakpointId; return 1; }).Sum(); #if DEBUG Debug.Assert(count == exceptionNames.Count()); #endif } }
private ReadOnlyDictionary<Guid, ExceptionCategorySettings> ReadDefaultSettings(HostConfigurationStore configStore) { Dictionary<Guid, ExceptionCategorySettings> categoryMap = new Dictionary<Guid, ExceptionCategorySettings>(); IEnumerable<Guid> categories = _commandFactory.GetSupportedExceptionCategories(); foreach (Guid categoryId in categories) { string categoryName; HostConfigurationSection categoryConfigSection; configStore.GetExceptionCategorySettings(categoryId, out categoryConfigSection, out categoryName); using (categoryConfigSection) { ExceptionCategorySettings categorySettings = new ExceptionCategorySettings(this, categoryConfigSection, categoryName); categoryMap.Add(categoryId, categorySettings); } } return new ReadOnlyDictionary<Guid, ExceptionCategorySettings>(categoryMap); }
private async Task UpdateCatagory(Guid categoryId, ExceptionCategorySettings categorySettings, SettingsUpdates updates) { // Update the category if (updates.NewCategoryState.HasValue && ( updates.NewCategoryState.Value != ExceptionBreakpointState.None || // send down a rule if the category isn't in the default state categorySettings.CurrentRules.Count != 0)) // Or if we have other rules for the category that we need to blow away { ExceptionBreakpointState newCategoryState = updates.NewCategoryState.Value; categorySettings.CategoryState = newCategoryState; categorySettings.CurrentRules.Clear(); IEnumerable <ulong> breakpointIds = await _commandFactory.SetExceptionBreakpoints(categoryId, null, newCategoryState); if (newCategoryState != ExceptionBreakpointState.None) { ulong breakpointId = breakpointIds.Single(); categorySettings.CurrentRules.Add("*", breakpointId); } } // Process any removes if (updates.RulesToRemove.Count > 0) { // Detach these exceptions from 'CurrentRules' List <ulong> breakpointsToRemove = new List <ulong>(); foreach (string exceptionToRemove in updates.RulesToRemove) { ulong breakpointId; if (!categorySettings.CurrentRules.TryGetValue(exceptionToRemove, out breakpointId)) { continue; } categorySettings.CurrentRules.Remove(exceptionToRemove); breakpointsToRemove.Add(breakpointId); } if (breakpointsToRemove.Count > 0) { await _commandFactory.RemoveExceptionBreakpoint(categoryId, breakpointsToRemove); } } // process any adds foreach (IGrouping <ExceptionBreakpointState, string> grouping in updates.RulesToAdd.GroupBy((pair) => pair.Value, (pair) => pair.Key)) { IEnumerable <string> exceptionNames = grouping; if (grouping.Key == categorySettings.CategoryState) { // A request to set an exception to the same state as the category is redundant unless we have previously changed the state of that exception to something else exceptionNames = exceptionNames.Intersect(categorySettings.CurrentRules.Keys); if (!exceptionNames.Any()) { continue; // no exceptions left, so ignore this group } } IEnumerable <ulong> breakpointIds = await _commandFactory.SetExceptionBreakpoints(categoryId, exceptionNames, grouping.Key); int count = exceptionNames.Zip(breakpointIds, (exceptionName, breakpointId) => { categorySettings.CurrentRules[exceptionName] = breakpointId; return(1); }).Sum(); #if DEBUG Debug.Assert(count == exceptionNames.Count()); #endif } }
private async Task FlushSettingsUpdates() { while (true) { // Delay sending updates until it has been ~50 ms since we have seen an update try { while (!_updateDelayCancelSource.IsCancellationRequested) { await Task.Delay(50, _updateDelayCancelSource.Token); lock (_updateLock) { if (_lastUpdateTime.HasValue) { uint millisecondsSinceLastUpdate = unchecked ((uint)(Environment.TickCount - _lastUpdateTime.Value)); // Clear this so that we don't think there is an unprocessed update at the end _lastUpdateTime = null; // Pick a number slightly less than the ms that we pass to Task.Delay as the resolution on Environment.TickCount is not great // and anyway we aren't trying to be precise as to how long we wait. if (millisecondsSinceLastUpdate >= 45) { break; } } else { break; } } } } catch (TaskCanceledException) { // Calls to EnsureSettingsUpdated cancel the delay } // Now send updates try { foreach (var categoryPair in _categoryMap) { ExceptionCategorySettings categorySettings = categoryPair.Value; SettingsUpdates settingsUpdate = categorySettings.DetachSettingsUpdate(); if (settingsUpdate == null) { continue; } await UpdateCatagory(categoryPair.Key, categorySettings, settingsUpdate); } } catch (MIException e) { _callback.OnError(string.Format(CultureInfo.CurrentUICulture, ResourceStrings.ExceptionSettingsError, e.Message)); } lock (_updateLock) { if (_lastUpdateTime == null) { // No more updates have been posted since the start of this iteration of the loop, we are done. _updateTask = null; _updateDelayCancelSource = null; break; } else { // An update may have been posted since our last trip arround the category loop, go again _lastUpdateTime = null; continue; } } } }