Подтвердить что ты не робот

Программно применять/деактивировать контрольные точки в Visual Studio

Независимо от других параметров, которые могут достичь того же результата (т.е. добавления точек останова вручную), можно ли программно добавить точку останова в исходный код проекта Visual Studio?

Например:

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

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

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

4b9b3361

Ответ 1

Ты вдохновил меня на то, чтобы тыкать с этим - спасибо, что не спал всю ночь.:) Здесь один из способов сделать это.

У Visual Studio действительно отличная поддержка точек останова. Одна из более крутых функций заключается в том, что вы можете сказать, что он запускает макрос Visual Studio при ударе точки останова. Эти макросы имеют полный доступ к среде разработки, то есть они могут делать все, что вы могли бы сделать вручную на клавиатуре, включая установку других точек останова.

Это решение состоит в том, чтобы: 1) установить в вашей программе попытку/улов верхнего уровня в вашей программе, чтобы поймать все исключения, 2) поставить точку останова в блоке catch, которая запускает ваш макрос, и 3) заставить макрос смотреть на исключение выяснить, откуда она взялась, и поставить там точку останова. Когда вы запускаете его в отладчике и возникает исключение, у вас будет новая точка останова в строке нарушения кода.

Возьмите эту программу:

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!");
        }
    }
}

Цель состоит в том, чтобы программно установить точку останова на throw в func3, когда вы запустили ее в отладчике и получили ошибку. Для этого сначала создайте новый макрос Visual Studio (я назвал my SetBreakpointOnException). Вставьте это в новый модуль MyDebuggerMacros или что-то еще:

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

Как только этот макрос будет установлен, вернитесь в блок catch и установите точку останова с F9. Затем щелкните правой кнопкой мыши по кругу красных точек и выберите "When Hit...". В нижней части появившегося диалогового окна есть возможность указать, чтобы он выполнял макрос - выпадал из списка и выбирал ваш макрос. Теперь вы должны получить новые контрольные точки, когда ваше приложение выдает необработанные исключения.

Заметки и оговорки об этом:

  • Я не гуру регулярных выражений, я уверен, что кто-то еще может взломать что-то лучше.
  • Это не обрабатывает вложенные исключения (свойство InnerException) - вы можете побить голову против этого, если хотите.:) Проверьте GetExpression ( "e.InnerException" ) и, возможно, рекурсия.
  • Он выполняет синтаксический анализ текста на строке StackTrace expetion, а не на более сложном анализе графа объектов (выкапывании в Exception.TargetSite и использовании отражения). Обычные оговорки касаются хрупкости этого подхода.
  • По какой-то причине кажется, что точка останова находится в каком-то "альтернативном пространстве". Как только начальный сеанс отладки завершится, вы не увидите новую точку останова в своем коде. Но это там, если вы снова запустите программу в отладчике, и такие вещи, как "Disable All Breakpoints", влияют на нее. Было бы неплохо узнать о том, что происходит, если кто-то хочет найти способ очистить это. Может быть, копаться в файле .suo?

Надеюсь, это поможет!

Ответ 2

Вы можете просто вызвать System.Diagnostics.Debugger.Break().

Вы также можете сообщить Visual Studio о том, чтобы разбить все исключения, даже обработанные, перейдя в меню на Debug->Exceptions... и проверив Thrown везде, где в настоящий момент только отмечен "Пользователь-необработанный".

Ответ 3

Это не очень отзывчиво на ваш вопрос, но вы можете заставить отладчик сломаться на основе условий, которые вы установили, используя Debug.Assert. Итак, вместо того, чтобы сказать: "В следующий раз, когда я запустил функцию, вызвавшую исключение, перерыв", вы можете добавить утверждения к своей функции, чтобы ломаться, когда условия не таковы, какими они должны быть. В конце концов, нет гарантии, что функция на этот раз вызовет исключение только потому, что в прошлый раз она исключила исключение.:)

Ответ 4

Я не думаю, что вы действительно можете "добавить точку останова", но вы можете поручить отладчику приостановить выполнение, чтобы вы могли проверить, что пошло не так, вызвав System.Diagnostics.Debugger.Break()

Ответ 5

Кроме того, Visual Basic имеет ключевое слово "Стоп", которое будет действовать как точка останова и прерывать выполнение.