Возврат из функции с использованием точки останова - PullRequest
6 голосов
/ 19 января 2012

Можно ли автоматически вернуться из функции, используя точку останова / точку трассировки?
Я не хочу перетаскивать точку выполнения или устанавливать ее с помощью CTRL + SHIFT + F10 каждый раз, когда достигается точка останова.
Я попытался «напечатать» следующие «сообщения» при попадании, но выполнение продолжается без изменений.

{return;}
{return null;}

Обратите внимание, что мне нужно вернуться из функции без фактического изменения кода.

Чтобы уточнить, что такое точка трассировки: "Точка трассировки - это точка останова с пользовательским действием, связанным с ней. При достижении точки трассировки отладчик выполняет указанное действие точки трассировки вместо или в дополнение к программному прерыванию. выполнение. " С MSDN .

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

Ответы [ 4 ]

7 голосов
/ 19 января 2012

В Visual Studio вы можете просто перетащить стрелку, которая указывает текущую строку кода во время отладки, в конец функции.

3 голосов
/ 19 января 2012

Хорошо, после небольшого количества копаний вокруг вас может сделать это - но это не сработает во всех случаях.

Осторожно, здесь используются макросы, и нельзя гарантировать работу с встроенными делегатами; или с методами, которые действительно должны что-то возвращать. Он автоматизирует процесс, описанный @juergen d и @Erno, когда достигается точка останова; используя очень простую эвристику, чтобы найти конец текущей функции.

Сначала вам нужно добавить этот макрос в вашу среду макросов (открыть с помощью ALT + F11 в VS). Этот код, вероятно, не так хорош, как мог бы быть, как я только что поспешил:)

Sub ExitStack()
    'get the last-hit breakpoint
    Dim breakPoint As EnvDTE.Breakpoint
    breakPoint = DTE.Debugger.BreakpointLastHit()
    'if the currently open file is the same as where the breakpoint is set
    '(could search and open it, but the debugger *should* already have done that)
    If (DTE.ActiveDocument.FullName = breakPoint.File) Then

        Dim selection As EnvDTE.TextSelection = DTE.ActiveDocument.Selection
        Dim editPoint As EnvDTE.EditPoint
        'move the cursor to where the breakpoint is actually defined
        selection.MoveToLineAndOffset(breakPoint.FileLine, breakPoint.FileColumn)

        Dim codeElement As EnvDTE.CodeElement
        codeElement = DTE.ActiveDocument.ProjectItem.FileCodeModel.CodeElementFromPoint(selection.ActivePoint, vsCMElement.vsCMElementFunction)
        'if a function is found, move the cursor to the last character of it
        If Not (codeElement Is Nothing) Then
            Dim lastLine As EnvDTE.TextPoint

            lastLine = codeElement.GetEndPoint()
            selection.MoveToPoint(lastLine)
            selection.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText)
            'execute the SetNextStatement command.  
            'Has to be done via ExecuteCommand
            DTE.ExecuteCommand("Debug.SetNextStatement")
        End If
    End If
End Sub

Теперь вы можете установить точку останова - щелкните ее правой кнопкой мыши и выберите пункт меню When hit... (я думаю, это работает только в VS2010). ScottGu описывает это в этом сообщении в блоге.

В диалоговом окне найдите макрос ExitStack, который вы только что вставили.

Запустите код с подключенным отладчиком, и при достижении точки останова оставшаяся часть кода функции должна быть пропущена. Это должно соответствовать другим приемам отладчика - например, условиям и т. Д.

Примечание - я использовал этот SO для решения проблемы, с которой я столкнулся; Первоначально я вызывал метод SetNextStatement отладчика напрямую, и он не работал

Я понятия не имею, как будут вести себя методы, которые должны возвращать - теоретически они должны возвращать любое возвращаемое значение local, но в некоторых случаях это просто не работает!

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

3 голосов
/ 19 января 2012

Два варианта:

  1. Если вы хотите, чтобы функция завершила свое выполнение и прервалась после возврата к вызывающей стороне.Нажмите «Выйти» (Shift-F11)
  2. Если вы хотите пропустить выполнение нескольких строк, перетащите желтый маркер на следующую строку, которую хотите выполнить.Помните, что перетаскивание маркера в определенное место может привести к порядку выполнения, который никогда не может произойти при запуске без вмешательства, поэтому результат может быть совершенно неверным.
1 голос
/ 05 февраля 2013

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

  1. Найдите адрес оператора возврата в нижней части функции, взломав его один раз, а затем просмотрев регистр EIPв окне «Регистры» или добавьте «Watch» для «@eip».
  2. Добавьте точку трассировки к линии, с которой вы хотите перейти.Помните, что скачок произойдет до того, как что-либо в строке будет выполнено.Содержимое точки трассировки должно быть {@eip = address} с использованием адреса из шага 1.
  3. Прибыль!

См. Также https://stackoverflow.com/a/14695736/301729

...