Nie zatrzymuj debugera na TYM wyjątku, gdy jest rzucany i przechwytywany


91

W narzędziach / wyjątkach ustawiłem opcję zatrzymywania debugera po wyrzuceniu wyjątku. Czy zostanie złapany, czy nie.

Jak wykluczyć wyjątek od tej reguły? Gdzieś w moim kodzie znajduje się przechwycony wyjątek, który jest częścią logiki programu. Więc oczywiście nie chcę, aby ten wyjątek zatrzymywał debuger za każdym razem, gdy zostanie trafiony.

Przykład: chcę zignorować wyjątek nullreference (który jest przechwytywany) w linii 344. Chcę się zatrzymać na wszystkich innych wyjątkach


6
Kiedy ten wyjątek jest częścią logiki programowania (pomyśl o tym, czy naprawdę musisz go zaimplementować w ten sposób) - powinien to być przynajmniej utworzony samodzielnie, wyprowadzony wyjątek. W ten sposób możesz zastosować rozwiązanie Briana.
tanascius


2
@tanascius - +1 Zgadzam się w większości przypadków Wyjątki nie są najlepszym sposobem podjęcia logicznej decyzji; jednak w niektórych przypadkach, na przykład podczas deserializacji, obsługa wyjątków jest czasami nieunikniona, więc jedyną rozsądną opcją jest throw> catch> handle.
jpierson,

2
@Ando sorry my bad. Moderowanie wielu kart jednocześnie jest wydajne, ale nie zawsze dokładne.

3
@tanascius: być może nadal będziesz musiał złapać znany wyjątek frameworka, zanim będziesz mógł wrzucić własny w odpowiedzi. Twoja sugestia nie zawsze jest możliwa.
Dan Puzey

Odpowiedzi:


40

Jeśli dobrze pamiętam, możesz użyć DebuggerStepThroughatrybutu w metodzie, która zawiera kod, którego nie chcesz, aby wyjątek był uruchamiany. Przypuszczam, że możesz wyodrębnić kod, który uruchamia irytujący wyjątek w metodzie i ozdobić go atrybutem.


31
Z odpowiedzi Malingera iz mojego doświadczenia wynika, że ​​ta odpowiedź jest nieprawidłowa. DebuggerStepThroughAtrybut nie ma wpływu na zachowanie debugera jest z wyjątkami pierwszy przypadek.
Michael Petrotta

5
@Tim, testowałem i NIE zatrzymuje się.
sprawdź

1
+1 działa w VS2010 dla czystego kodu .NET 4.0 i Silverlight 4 dla nieobsługiwanych wyjątków.
Mike Post,

6
Ważna uwaga: to nie działa w przypadku metod typu async-await. Więcej tutaj
i3arnon

8
Według MSDN DebuggerStepThroughatrybut nie ma znaczenia dla środowiska CLR. Jest interpretowany przez debuggery. Wygląda na to, że nie działa niezawodnie w różnych okolicznościach, a to DebuggerHiddenbędzie działać niezawodnie stackoverflow.com/a/3455100/141172
Eric J.

65

DebuggerHidden jest twoim przyjacielem!

Środowisko uruchomieniowe języka wspólnego nie dołącza żadnej semantyki do tego atrybutu. Jest przeznaczony do użytku przez debuggery kodu źródłowego. Na przykład debuger programu Visual Studio 2005 nie zatrzymuje się w metodzie oznaczonej tym atrybutem i nie zezwala na ustawienie punktu przerwania w metodzie. Inne atrybuty debugera rozpoznawane przez debuger programu Visual Studio 2005 to DebuggerNonUserCodeAttribute i DebuggerStepThroughAttribute.

Testowany na VS2010 i działa świetnie.

Chociaż DebuggerStepThroughwydaje się, że działa również dla niektórych konkretnych wersji debugera, DebuggerHiddenwydaje się działać w szerszym zakresie sytuacji w oparciu o komentarze do obu odpowiedzi.

Zauważ, że obie opcje nie działają obecnie z metodami blokowymi iteratora lub metodami async / await . Można to naprawić w późniejszej aktualizacji programu Visual Studio.


pracuje nad VS2008. Musisz zastosować to do całej metody, w tym bloku catch, albo po prostu złamiesz gdzie indziej
Mark Heath

1
Dodałem ten atrybut do metody, a debugger po prostu zatrzymał się na metodzie wywołania. Czy coś mi brakuje?
Doogal

1
Tak powinno być. aby tego uniknąć, będziesz musiał obsłużyć wyjątek ... Lub alternatywnie oznacz również metodę wywołującą DebuggerHidden...
Shimmy Weitzhandler

1
Należy zauważyć, że atrybut DebuggerStepThrough powinien wystarczyć, aby uniknąć przerwania wyjątków. DebuggerHidden działa jak połączenie obu DebuggerNonUserCode i atrybutu DebuggerStepThrough.
jpierson,


14

DebuggerStepThrough to ten, który ma być używany, aby uniemożliwić debugerowi przerwanie metody, w której istnieje próba / przechwycenie.

Ale działa tylko wtedy, gdy nie odznaczysz opcji „Włącz tylko mój kod (tylko zarządzany)” w ustawieniach ogólnych opcji debugowania programu Visual Studio (menu Narzędzia / Opcje, debugowanie węzła / Ogólne) ...

Więcej informacji na temat tego atrybutu można znaleźć pod adresem http://abhijitjana.net/2010/09/22/tips-on-debugging-using-debuggerstepthrough-attribute/

DebuggerHidden po prostu uniemożliwi Debuggerowi wyświetlenie metody, w której jest zgłaszany wyjątek. Zamiast tego pokaże pierwszą metodę na stosie, która nie jest oznaczona tym atrybutem ...


1
Zauważ, że to już nie działa domyślnie w VS 2015, zobacz blog VS, aby to włączyć
bhh

Niestety obejście VS 2015 nie działa w VS 2019.
Jonathan Allen,

13

Atrybuty określone w innych odpowiedziach (i innych, takich jak DebuggerNonUserCodeatrybut) nie działają już domyślnie w ten sam sposób w programie Visual Studio 2015. Debugger będzie przerywał wyjątki na rynku metod z tymi atrybutami, w przeciwieństwie do starszych wersji VS. Aby wyłączyć ulepszenie wydajności, które zmieniło ich zachowanie, musisz zmienić ustawienie rejestru:

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

Więcej informacji można znaleźć na blogu Visual Studio .

(To prawdopodobnie powinien być komentarz do najlepszej odpowiedzi, ale nie mam wystarczającej liczby przedstawicieli)


3

Nie jesteś w stanie wyodrębnić wyjątku rzuconego w określonym miejscu w kodzie. Możesz jednak wyłączyć wyjątki określonego typu.

Jeśli twój własny kod zgłasza dany wyjątek, uczyniłbym go niestandardowym wyjątkiem, pochodzącym z wszystkiego, co pasuje, a następnie wyłączam łamanie debugowania dla tego typu pochodnego.

Wyłączenie wyjątków systemowych jako NullReferenceException wpłynie na cały system, co oczywiście nie jest pożądane podczas programowania.

Zauważ, że istnieją dwa rodzaje zachowań związanych z zerwaniem dla wyjątków:

  • Zgłoszony: jeśli wybrana, przerywa, gdy tylko zostanie zgłoszony wyjątek tego typu
  • Nieobsługiwany przez użytkownika: jeśli wybrano, przerywa tylko wtedy, gdy wyjątek tego typu nie jest obsługiwany przez try / catch.

Możesz usunąć zaznaczenie „Thrown” dla wyjątku NullReferenceException, co zapewni ci korzyść polegającą na tym, że nie przerywa się za każdym razem, gdy system przechodzi przez dany wiersz w kodzie, ale nadal się psuje, jeśli masz nieobsłużone oczekiwanie NullReference występujące w innych częściach system.


3
Dodanie atrybutu DebuggerStepThrough do metody w programie Visual Studio 2010 uniemożliwi debugerowi zatrzymanie nieobsługiwanego wyjątku przez metodę.
Tim Murphy

Testowałem i to nie zapobiega; to wciąż się zatrzymuje
Shimmy Weitzhandler,

1
@Shimmy - działa dla mnie! Upewnij się, że stosujesz DebuggerStepThrough do każdej metody od punktu, w którym jest ona zgłaszana, aż do punktu, w którym wyjątek ma być widoczny w stosie wywołań. Jeśli złapiesz wyjątek i obsłużysz go w hierarchii wywołań, w której wszystkie metody są ozdobione DebuggerStepThrough, nigdy nie powinieneś widzieć VS break dla tego wyjątku.
jpierson,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.