Programowo apply / deactivate breakpoints in Visual Studio

Niezależnie od innych opcji, które mogą osiągnąć ten sam wynik (np. dodanie punktów przerwania ręcznie), czy można programowo dodać punkt przerwania do kodu źródłowego projektu Visual Studio?

Takie jak:

try
{
    FunctionThatThrowsErrors(obj InscrutableParameters);
}
catch(Exception ex)
{
    Log.LogTheError(ex);
    AddBreakPointToCallingFunction();
}

W ten sposób, gdy uruchomisz debugowanie następnym razem, automatycznie ustawisz punkty przerwania we wszystkich punktach, które spowodowały problemy podczas ostatniego uruchomienia.

Nie mówię, że jest to szczególnie przydatny sposób debugowania. Zastanawiam się, czy możliwości są tam.

Author: Peter Mortensen, 2009-05-09

5 answers

Zainspirowałaś mnie, żebym się tym pokręciła-dzięki, że nie mogłam zasnąć całą noc. :) Jest jeden sposób, aby to zrobić.

Visual Studio ma naprawdę świetną obsługę punktów przerwania. Jedną z fajniejszych funkcji jest to, że możesz powiedzieć mu, aby uruchomił Makro Visual Studio, gdy punkt przerwania zostanie uderzony. Te makra mają pełny dostęp do środowiska programistycznego, tzn. mogą robić wszystko, co można zrobić ręcznie przy klawiaturze, w tym ustawiać inne punkty przerwania.

To rozwiązanie jest do 1) umieścić najwyższy poziom try/catch w programie, aby wyłapać wszystkie wyjątki, 2) umieść punkt przerwania w bloku catch, który uruchamia Twoje makro, i 3) niech makro spojrzy na wyjątek, aby dowiedzieć się, skąd pochodzi, i umieść tam punkt przerwania. Gdy uruchomisz go w debuggerze i pojawi się wyjątek, będziesz miał nowy punkt przerwania w naruszającej linii kodu.

Weź ten przykładowy program:

using System;

namespace ExceptionCallstack
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                func1();
            }
            catch (Exception e)
            {
                Console.WriteLine("Oops");
                Console.ReadKey();
            }
        }

        static void func1()
        {
            func2();
        }

        static void func2()
        {
            func3();
        }

        static void func3()
        {
            throw new Exception("Boom!");
        }
    }
}
Celem jest programowo ustawianie punktu przerwania na tym throw w func3, gdy uruchomisz go w debugger i uzyskać błąd. Aby to zrobić, najpierw Utwórz nowe makro Visual Studio (nazwałem moje SetBreakpointOnException). Wklej to do nowego modułu MyDebuggerMacros czy jakoś tak:
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics
Imports System.Text.RegularExpressions

Public Module DebuggerMacros

    Sub SetBreakpointOnException()

        Dim output As String = ""

        Dim stackTrace As String = DTE.Debugger.GetExpression("e.StackTrace").Value
        stackTrace = stackTrace.Trim(New Char() {""""c})
        Dim stackFrames As String() = Regex.Split(stackTrace, "\\r\\n")

        Dim r As New Regex("^\s+at .* in (?<file>.+):line (?<line>\d+)$", RegexOptions.Multiline)
        Dim match As Match = r.Match(stackFrames(0))
        Dim file As String = match.Groups("file").Value
        Dim line As Integer = Integer.Parse(match.Groups("line").Value)

        DTE.Debugger.Breakpoints.Add("", file, line)

    End Sub

End Module

Gdy makro jest już gotowe, wróć do bloku catch i ustaw punkt przerwania za pomocą F9. Następnie kliknij prawym przyciskiem myszy czerwone kółko punktu przerwania i wybierz "po trafieniu...". Na dole okna dialogowego wynikowego znajduje się opcja, aby powiedzieć mu, aby uruchomił makro - rozwijaj listę i wybierz swoje makro. Teraz ty powinien uzyskać nowe punkty przerwania, gdy aplikacja wyrzuca nieobsługiwane wyjątki.

Uwagi i Zastrzeżenia na ten temat:

  • jestem Nie regex guru, jestem pewien, że ktoś inny może stworzyć coś lepszego.
  • to nie obsługuje zagnieżdżonych WYJĄTKÓW ( właściwość InnerException) - możesz to zrobić, jeśli chcesz. :) Sprawdź GetExpression ("e.InnerException") i recurse, być może.
  • analizuje tekst na łańcuchu StackTrace excpetion, nie bardziej wyrafinowana analiza grafów obiektowych (przekopywanie się w wyjątek.TargetSite i korzystanie z odbicia). Typowe zastrzeżenia dotyczą kruchości tego podejścia.
  • z jakiegoś powodu wydaje się umieszczać punkt przerwania w jakiejś "alternatywnej przestrzeni". Po zakończeniu pierwszej sesji debugowania nie widzisz nowego punktu przerwania w kodzie. Ale jest tam, jeśli uruchomisz program ponownie w debuggerze, a rzeczy takie jak "Wyłącz wszystkie punkty przerwania" wpływają na to. Byłoby miło dowiedzieć się o o co chodzi, jeśli ktoś ma ochotę to posprzątać. Może grzebanie w ... akta suo?
Mam nadzieję, że to pomoże!
 39
Author: David Pope,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-09 11:07:30

Możesz po prostu zadzwonić System.Diagnostics.Debugger.Break().

Możesz również powiedzieć Visual Studio, aby złamał wszystkie wyjątki, nawet te obsługiwane, przechodząc do menu Debug->Exceptions... i sprawdzając Thrown wszędzie, gdzie jest obecnie zaznaczone tylko "użytkownik nieobsługiwany".

 44
Author: Joel Coehoorn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-08 21:12:46

Nie odpowiada na twoje pytanie, ale możesz spowodować, że debuger się zepsuje na podstawie warunków ustawionych za pomocą debugera .Assert . Tak więc, zamiast mówić "następnym razem, gdy uruchomię funkcję, która spowodowała wyjątek, break", możesz dodać twierdzenia do swojej funkcji, aby złamać, gdy warunki nie są takie, jakie powinny być. W końcu nie ma gwarancji, że funkcja rzuci wyjątek tym razem tylko dlatego, że rzuciła wyjątek ostatnim razem. :)

 4
Author: JP Alioto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-08 21:12:06

Nie wydaje mi się, że możesz "dodać punkt przerwania", ale możesz polecić debuggerowi zawieszenie wykonania, aby sprawdzić, co poszło nie tak, wywołując System.Diagnostyka.Debugger.Break ()

 2
Author: Thomas Levesque,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-08 21:09:09

Visual Basic ma również słowo kluczowe Stop, które będzie zasadniczo działać jako punkt przerwania i wykonanie przerwania.

 0
Author: Icemanind,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-25 15:56:45