Почему условные точки останова замедляют мою программу?
Когда я отлаживаю что-то, что выходит из строя внутри цикла, скажем, на 600-й итерации, это может быть болью, чтобы ломаться для каждого. Поэтому я попытался установить условную точку останова, чтобы только разорвать, если я = 600. Это работает, но теперь для достижения этой точки требуется почти полная минута, где раньше она была почти мгновенной. Что происходит, и есть ли способ исправить это?
Ответы
Ответ 1
При нажатии точки останова Windows останавливает процесс и уведомляет об отладчике. Он должен переключать контексты, оценивать условие, решать, что нет, вы не хотите получать уведомления об этом, перезапустить процесс и вернуться обратно. Это может занять много процессорных циклов. Если вы делаете это в жесткой петле, это займет несколько порядков больше циклов процессора, чем одна итерация цикла.
Если вы хотите немного поработать с вашим кодом, есть способ сделать условные точки останова без возникновения всех этих накладных расходов.
if <condition here> then
asm int 3 end;
Это простая инструкция по сборке, которая вручную отправляет уведомление о прерывании в ОС. Теперь вы можете оценить свое состояние внутри программы, не переключая контексты. Просто убедитесь, что выберете его, когда закончите с ним. Если int 3 отключается внутри программы, не подключенной к отладчику, это вызовет исключение.
Ответ 2
Это замедляет работу, потому что каждый раз, когда вы достигаете этой точки, она должна проверять ваше состояние.
То, что я обычно делаю, - это временно создать другую переменную, подобную этой (в C, но в Delphi она должна выполняться).
int xyzzynum = 600;
while (true) {
doSomething();
if (--xyzzynum == 0)
xyzzynum = xyzzynum;
}
то я положил неконстантную точку останова на строку "xyzzynum = xyzzynum;"
.
Программа работает на полной скорости, пока она не пройдет через цикл 600 раз, поскольку отладчик просто выполняет обычное прерывание прерывания, а не проверяет условия каждый раз.
Вы можете сделать условие настолько сложным, насколько хотите.
Ответ 3
В дополнение к ответу Мейсона, вы можете сделать сборку только для 3-го сборника, если программа построена с установленным условным условным обозначением:
{$ifdef debug}
{$message warn 'debug breakpoint present in code'}
if <condition here> then
asm int 3 end;
{$endif}
Итак, когда вы отлаживаете идею, у вас есть опция debug в параметрах проекта. Когда вы создадите конечный продукт для своих клиентов (с вашей сборкой script?), Вы не включите этот символ, поэтому он не будет скомпилирован.
Я также включил директиву компиляции $message, поэтому при компиляции вы увидите предупреждение, позволяющее вам знать, что код все еще существует. Если вы делаете это везде, где вы используете int 3, у вас будет хороший список мест, которые вы можете дважды щелкнуть, чтобы сразу перейти к нарушившемуся коду.
N @
Ответ 4
Пояснения Мейсона неплохие.
Его код можно сделать немного более безопасным, протестировав его под отладчиком:
if (DebugHook <> 0) and <your specific condition here> then
asm int 3 end;
Это не будет делать ничего, если приложение работает нормально и остановится, если оно работает под отладчиком (запущено ли из IDE или подключено к отладчику).
И с булевым ярлыком <your specific condition here>
даже не будет оцениваться, если вы не находитесь под отладчиком.
Ответ 5
Условные точки останова в любом отладчике (я просто предполагаю здесь) требуют, чтобы процесс перебрасывался назад и вперед каждый раз между вашей программой и отладчиком каждый раз, когда ударяется точка останова. Этот процесс занимает много времени, но я не думаю, что вы можете что-то сделать.
Ответ 6
Нормальные условия останова работают, вставляя соответствующую команду разрыва в код, а затем проверяя условия, которые вы указали. Он будет проверяться на каждой итерации, и вполне возможно, что способ выполнения проверки отвечает за задержку, поскольку маловероятно, что отладчик компилирует и вставляет полный код проверки и кода останова в существующий код.
Способ, которым вы могли бы ускорить это, заключается в том, что вы помещаете условие, за которым следует op, без побочного эффекта в код напрямую и прерывать этот op. Просто не забудьте удалить условие и op, когда закончите.