Не останавливайте отладчик в ЭТОЙ исключительной ситуации, когда он брошен и пойман

В инструментах / исключениях я установил параметр, при котором отладчик останавливается при возникновении исключения. Будь то пойман или нет.

Как исключить исключение из этого правила? Где-то в моем коде есть пойманное исключение, которое является частью логики программы. Поэтому я, очевидно, не хочу, чтобы это исключение останавливало отладчик при каждом его срабатывании.

Пример: я хочу игнорировать исключение нулевой ссылки (которое перехватывается) в строке 344 . Я хочу остановиться на всех других исключениях

6 ответов

Решение

Если я правильно помню, вы можете использовать DebuggerStepThrough атрибут метода, который содержит код, который вы не хотите, чтобы исключение срабатывало. Я полагаю, вы можете изолировать код, который вызывает раздражающее исключение в методе, и украсить его атрибутом.

DebuggerHidden твой друг!

Общеязыковая среда выполнения не придает семантики этому атрибуту. Он предоставляется для использования отладчиками исходного кода. Например, отладчик Visual Studio 2005 не останавливается в методе, помеченном этим атрибутом, и не позволяет устанавливать точку останова в методе. Другими атрибутами отладчика, распознаваемыми отладчиком Visual Studio 2005, являются DebuggerNonUserCodeAttribute и DebuggerStepThroughAttribute.

Проверено на VS2010 и отлично работает.

В то время как DebuggerStepThrough кажется, также работает для некоторых конкретных версий отладчика, DebuggerHidden кажется, работает для более широкого диапазона ситуаций, основанных на комментариях к обоим ответам.

Обратите внимание, что оба параметра в настоящее время не работают с блочными методами итераторов или с асинхронными / ожидающими методами. Это может быть исправлено в более позднем обновлении Visual Studio.

DebuggerStepThrough - это тот, который используется для предотвращения сбоя отладчика в методе, в котором есть try / catch.

Но это работает только в том случае, если вы не сняли флажок "Включить только мой код (только управляемый)" в общих настройках параметров отладки Visual Studio (меню "Инструменты / Параметры", "Отладка узла" / "Общие")...

Больше информации об этом атрибуте на http://abhijitjana.net/2010/09/22/tips-on-debugging-using-debuggerstepthrough-attribute/

DebuggerHidden просто не позволит отладчику отображать метод, в котором выдается исключение. Вместо этого он покажет первый метод в стеке, который не помечен этим атрибутом...

Атрибуты, указанные в других ответах (и других, таких как DebuggerNonUserCode атрибут) больше не работает таким же образом по умолчанию в Visual Studio 2015. Отладчик будет работать с исключениями на рынке методов с этими атрибутами, в отличие от более старых версий VS. Чтобы отключить повышение производительности, которое изменило их поведение, необходимо изменить параметр реестра:

reg add HKCU\Software\Microsoft\VisualStudio\14.0_Config\Debugger\Engine /v AlwaysEnableExceptionCallbacksOutsideMyCode /t REG_DWORD /d 1

Более подробную информацию можно найти в блоге Visual Studio.

(Вероятно, это должен быть комментарий к верхнему ответу, но мне не хватает представителя)

Вы не можете выделить исключение, выброшенное в определенном месте в вашем коде. Однако вы можете отключить исключения определенного типа.

Если ваш собственный код генерирует исключение, о котором идет речь, я бы сделал его настраиваемым исключением, полученным из всех подходящих вариантов, а затем отключил бы отладку в этом производном типе.

Отключение системных исключений как NullReferenceException повлияет на всю систему, что, конечно, нежелательно при разработке.

Обратите внимание, что для исключений существует два вида прерываний:

  • Брошенный: если выбрано, прерывается, как только выбрасывается исключение этого типа
  • Необработанный пользователем: если выбрано, прерывается, только если исключение этого типа не обрабатывается попыткой / перехватом.

Вы можете снять флажок "Брошено" для исключения NullReferenceException, которое даст вам преимущество: не прерывать каждый раз, когда ваша система пропускает соответствующую строку в вашем коде, но по-прежнему прерывать, если у вас есть необработанное исключение NullReference, возникающее в других частях система.

Итак, я нашел решение, которое работает в VS 2019, оно немного сложнее, чем мне хотелось бы, но для моего варианта использования необходимо было решить эту проблему.

инструкции

Сначала переместите код, вызывающий проблему, в его собственную функцию, чтобы вы не подавляли исключения в окружающем коде, и отметьте его атрибутом DebuggerStepThrough (или DebuggerHidden тоже работает).

      [DebuggerStepThrough]
public void ExceptionThrowingFunction()
{
    //.. Code that throws exception here
}

Тогда назовите это так

      OutsourceException(ExceptionThrowingFunction);

Затем возьмите отдельный проект (модуль), в котором либо вам не нужно подавлять все исключения, либо он специально создан для этой цели. Важно, чтобы это был отдельный проект, чтобы ваш основной проект по-прежнему мог прерваться из-за этого типа исключения. В моем случае у меня уже был небольшой служебный проект под названием SharedFunctions, поэтому я поместил его туда. Код довольно стабилен и большую часть времени не требует отладки.

В классе ExceptionUtils я добавил следующие функции:

      public static T OutsourceException<T>(Func<T> func)
{
    T result = default;
    try
    {
        result = func.Invoke();
    }
    catch { }
    return result;
}

public static T OutsourceException<T, Y>(Func<T, Y> func, Y arg)
{
    T result = default;
    try
    {
        result = func.Invoke(arg);
    }
    catch { }
    return result;
}

public static void OutsourceException<T>(Action<T> action, T arg)
{
    try
    {
        action.Invoke(arg);
    }
    catch { }
}

Возможно, вам придется добавить больше из них, они охватывают только базовые случаи, когда у вас есть аргументы от 0 до 1 в вашей функции.

Наконец, когда вы запустите код, он все равно прервет исключение в функции Outsource с таким сообщением: Если вы установите нижний флажок (в этом примере 'SharedFunctions.dll'), он добавит правило, что исключение должно игнорироваться, если выброшено из этой сборки. Как только это будет проверено, исключение должно быть подавлено. Все остальные исключения в основной сборке этого типа по-прежнему будут работать нормально.

Что здесь происходит?

Из-за изменений в VS 2015, которые нарушили [DebuggerHidden] и подобные атрибуты (см. в Сообщениеблоге, связанное с другим ответом здесь), атрибуты теперь передают исключение вызывающему классу, и отладчик просто прерывается. Если мы переместим вызывающий класс в другую сборку, мы сможем подавить исключение, используя систему условий исключения.

Почему бы просто не исправить исключение?

Некоторые исключения невозможно полностью удалить из кода, например, когда вы пытаетесь получить доступ Package.Currentв приложении UWP. Он всегда будет вызывать исключение в отладчике, и это может быть разрешено только Microsoft. Другое решение в этом случае - просто окружить его #if !DEBUG но есть и другие случаи, когда это нецелесообразно.

Другие вопросы по тегам