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

91

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

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

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

MichaelD
источник
6
Когда это исключение является частью вашей логики программирования (подумайте, если вам действительно нужно реализовать его таким образом), тогда это должно быть, по крайней мере, собственное созданное производное исключение. Таким образом можно применить раствор Брайана.
tanascius
Вот проблема: stackoverflow.com/questions/1957907/…
MichaelD
2
@tanascius - +1 Я согласен в большинстве случаев Исключения - не лучший способ логического решения; однако в некоторых случаях, например, когда десериализация обработки исключений иногда неизбежна, поэтому throw> catch> handle - единственный разумный вариант.
jpierson 07
2
@ И извини, что плохо. Одновременная модерация нескольких вкладок эффективна, но не всегда точна.
3
@tanascius: возможно, вам все равно придется перехватить известное исключение фреймворка, прежде чем вы сможете отправить свое собственное в ответ. Ваше предложение не всегда возможно.
Дэн Пьюзи

Ответы:

40

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

Крис Чоу
источник
31
Из ответа Малинджера и моего опыта этот ответ кажется неверным. DebuggerStepThroughАтрибут не влияет на поведение отладчика с первым шансом исключением.
Майкл Петротта
5
@ Тим, я тестировал, и он НЕ останавливается. проверить мой ответ: stackoverflow.com/questions/1420390/3455100#3455100
Шимми Вейтцхандлер
1
+1 работает в VS2010 для чистого кода .NET 4.0 и Silverlight 4 для необработанных исключений.
Майк Пост,
6
Важное примечание: это не работает для методов типа async-await. Подробнее здесь
i3arnon
8
Согласно MSDN, DebuggerStepThroughатрибут не имеет значения для CLR. Это интерпретируется отладчиками. Похоже, что он не работает надежно при различных обстоятельствах, и он DebuggerHiddenбудет работать надежно stackoverflow.com/a/3455100/141172
Эрик Дж
65

DebuggerHidden твой друг!

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

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

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

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

Шимми Вайцхандлер
источник
работаю на VS2008. Вы должны применить его ко всему методу, включая блок catch, иначе вы просто сломаетесь где-нибудь еще,
Марк Хит
1
Я добавил этот атрибут в метод, и вместо этого отладчик просто остановился на вызывающем его методе. Я что-то упускаю?
Doogal
1
Так и должно быть. чтобы избежать этого, вам придется обработать исключение ... Или, в качестве альтернативы, также отметить метод вызывающего абонента DebuggerHidden...
Шимми Вейцхандлер
1
Обратите внимание, что атрибута DebuggerStepThrough должно быть достаточно, чтобы избежать прерывания при исключениях. DebuggerHidden действует как комбинация DebuggerNonUserCode и атрибута DebuggerStepThrough.
jpierson 07
14

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

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

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

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

Валерий Летрое
источник
1
Обратите внимание, что это больше не работает по умолчанию в VS 2015, см. Блог VS, чтобы узнать, как его включить
бхх,
К сожалению,
Джонатан Аллен,
13

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

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

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

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

бхх
источник
3

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

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

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

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

  • Выброшено: если выбрано, прерывается, как только создается исключение этого типа.
  • User-unhandled: если выбрано, прерывается, только если исключение этого типа не обрабатывается с помощью try / catch.

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

Ларс Уденгаард
источник
3
Добавление атрибута DebuggerStepThrough к методу в Visual Studio 2010 предотвратит остановку отладчиком необработанного исключения, вызванного методом.
Тим Мерфи,
Я тестировал и это не мешает; он все еще останавливается
Шимми Вайцхандлер
1
@Shimmy - У меня работает! Убедитесь, что вы применяете DebuggerStepThrough к каждому методу с момента его создания до момента, когда вы хотите, чтобы исключение стало видимым в стеке вызовов. Если вы перехватываете исключение и обрабатываете его в иерархии вызовов, где все методы украшены DebuggerStepThrough, вы никогда не увидите прерывания VS для этого исключения.
jpierson 07