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);
        }
Esempio n. 2
0
 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());
        }
Esempio n. 4
0
        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));
        }
Esempio n. 5
0
        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));
        }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
        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
            }
        }
Esempio n. 8
0
        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);
        }
Esempio n. 9
0
        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
            }
        }
Esempio n. 10
0
        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;
                    }
                }
            }
        }
Esempio n. 11
0
 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();
     }
 }