В Delphi: как пропустить разделы кода во время отладки?

Я часто ошибочно вхожу в код, который мне неинтересен при отладке в Delphi.

Начнем с того, что я знаю, что вы можете перешагнуть с F8, и что вы можете перейти к определенной строке с помощью f4.

Пример:

function TMyClass.DoStuff():Integer;
begin
  // do some stuff
  bla();
end;

procedure TMyClass.Foo()
begin
  if DoStuff()=0 then // press F7 when entering this line
    beep;
end;

Пример: я хочу перейти в метод DoStuff(), нажав F7, но вместо того, чтобы идти туда, я сначала заканчиваю FastMM4.FastGetMem(), который представляет собой массивный блок кода сборки, который, очевидно, мне неинтересен в настоящий момент.

Есть несколько способов обойти это, и я не люблю их:

  • Добавьте точку останова на "bla" (почти бесполезно, если вы хотите только войти в DoStuff в особых случаях, например, итерация 23498938);

  • Вместо того, чтобы нажимать F7, вручную переместите курсор на "bla" и нажмите F4 (работает для этого простого примера. На практике это не так);

  • В случае FastMM: временно отключить fastmm;

Есть ли способ намекнуть IDE, что я никогда заинтересован в том, чтобы переходить в определенный блок кода, или мне всегда приходится устанавливать дополнительные контрольные точки или использовать F4, чтобы избежать этого

Я надеюсь на какую-то магическую директиву компилятора, например {$ NODEBUG BEGIN/END} или что-то в этом роде.

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

Обновление: возможно, codegear должен ввести что-то вроде пропусков (в отличие от точек останова): -)

Ответ 1

Существует "волшебный переключатель узла узла". {$ D-} отключит генерацию кода отладки. Поместите это вверху вашего модуля FastMM, и вы не сможете его отслеживать. И если вы действительно входите в функцию, в которую вы не хотите быть, SHIFT-F8 выведет вас очень быстро. ( ПРЕДУПРЕЖДЕНИЕ: Не используйте SHIFT-F8 из подпрограммы сборки-кода, которая работает со стеком. Непредсказуемое поведение может привести к тому, что F4 находится внизу.)

Ответ 2

Если вы переходите в FastMM-код, тогда происходят операции с памятью. Код, который вы указали, не имеет операций с памятью, поэтому ваш вопрос является неполным. Я постараюсь угадать, что вы имели в виду.

Когда подпрограмма имеет локальные переменные типов, управляемых компилятором (например, строки, интерфейсы или динамические массивы), пролог функции имеет нетривиальную работу. В прологе также указывается опорный счет входных параметров. Отладчик представляет пролог в строке begin функции. Если текущая точка выполнения - это строка, и вы "входите" в нее, вы попадете в RTL-код для управления специальными типами. (Я бы не ожидал, что FastMM тоже будет задействован там, но, возможно, все изменилось с того, к чему я привык.) В этой ситуации легко сделать "перешагнуть" строку begin, а не Это; используйте F8.

Если вы действительно нажимаете F7 при вводе выделенной строки, вы делаете это неправильно. Это переход в строку begin, а не строку, где вызывается DoStuff. Поэтому, если вы попали в код FastMM, это не имеет никакого отношения к реализации DoStuff. Чтобы отладить вызов DoStuff, текущая точка выполнения уже должна быть линией с вызовом на ней.

Если вы хотите отлаживать DoStuff на итерации 23498938, тогда вы можете установить условную точку останова в этой функции. Нажмите в желобе, чтобы создать нормальную точку останова, а затем щелкните его правой кнопкой мыши, чтобы отобразить его свойства. Там вы можете определить условие, которое будет оцениваться каждый раз, когда выполнение достигает этой точки. Отладчик останавливается там, когда условие истинно. Нажмите F8, чтобы "перешагнуть" вызов DoStuff, и если условие истинно, отладчик остановится там, как если бы вы нажали F7.

Вы можете переключить опцию "использовать debug DCUs", чтобы избежать перехода на большинство блоков RTL и VCL. Я не знаю, включен ли FastMM в этот набор. Ключевое различие заключается в том, скомпилированы ли DCU, с которыми вы связаны, с отладочной информацией. Этот параметр изменяет путь к библиотеке для включения или исключения подкаталога, в котором находятся отладочные DCU. Я думаю, вы можете настроить набор включенных или исключенных каталогов отладки, чтобы добавить или удалить настраиваемый набор каталогов на основе настроек "debug DCUs".

Назад к точкам останова. Вы можете настроить группы точек останова, назначив имена своим точкам останова. Вы можете использовать расширенную точку останова, чтобы включить или отключить именованную группу точек останова при ее передаче. (Группы останова могут иметь только одну точку останова, если хотите.) Например, если вы хотите только разорвать местоположение X, если вы также передали какое-то другое место Y в своей программе, вы можете установить отключенную точку останова на X и неразрывную точку останова в Y. Установите для параметра "активировать группы" значение Y для включения группы X.

Вы также можете использовать отключенные точки останова без автоматического включения и отключения. Точки останова отображаются в окне отладки "breakpoints". Если вы перейдете через DoStuff, и вы решите, что хотите проверить bla на этот раз, перейдите в окно точки останова и включите точку останова в bla. Нет необходимости переходить к реализации bla, чтобы установить там точку останова.

Подробнее о передовых контрольных точках см. Использование нелокальных точек останова в Delphi и статьи Кэри Дженсена из нескольких лет назад.

Ответ 3

Возможно, я пропустил что-то с вашим сообщением, но с FastMM4 вы можете отредактировать файл FastMM4Options.Inc и удалить ".". из следующего:


Из FastMM4Options.inc ****

{Включить эту опцию, чтобы подавить генерацию отладочной информации для  Блок FastMM4.pas. Это предотвратит включение интегрированного отладчика в  код менеджера памяти.}

{$. define NoDebugInfo}


При перекомпиляции (возможно, потребуется создать) отладчик (не должен) больше не отлаживает код FastMM.

Ответ 4

Используйте предварительно скомпилированный DCU без ошибок от FasmMM

Ответ 5

В файле проекта dpr я использую

uses
{$IFNDEF DEBUG} FastMM4, {$ENDIF}
  ... // other units

чтобы исключить FastMM4 во время режима отладки. Не требует изменений в FastMM4, поэтому мне не нужно забывать добавлять {$ D-} в FastMM, когда я перехожу к другой версии.

Ответ 6

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

Одно предостережение: завершение кода также зависит от пути просмотра, поэтому вы можете столкнуться с ситуациями, когда при необходимости завершается завершение кода.

Ответ 7

Хотя это не прямой ответ на ваш вопрос, вы можете изменить свое первое предлагаемое решение, поставив точку останова на bla, которая разрешена только тогда, когда передается точка останова в Foo (или какое-либо другое условие вашего выбора, например, итерация рассчитывать). Тогда он будет разорваться только тогда, когда вы захотите.

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

Ответ 8

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

Лучшее, что вы можете сделать, когда попадаете в рутину, в которой вы не хотите быть, - это использовать Shift + F8, который будет работать до возвращения. Затем выполните F7 или F8, чтобы выйти из процедуры.


Хммм. Теперь я вижу, что Мейсон отвечает. Узнал что-то. Спасибо, Мейсон. +1