Про брейкпойнты

    Думаю не ошибусь, если напишу, что каждый программист когда-либо пользовался отладчиком, отлаживал программу пошагово, устанавливал брейкпойнты и т.п. При этом некоторые программисты не любят отлаживать. Другие — обожают. А большинство просто использует отладчик не задумываясь о любви и ненависти, ведь это просто еще один удобный инструмент для работы.
    Для многих программистов отладчики — это черный ящик. Они умеют с ним обращаться, но не знают, как он работает. Я не говорю, что это плохо — в подавляющем большинстве случаев можно легко отлаживать программу без знания устройства отладчика.
    А для тех, кто хочет заглянуть внутрь черного ящика, я написал эту небольшую статью.
    Тут я расскажу про одну из самых загадочных (по крайней мере для меня) возможностей отладчиков — про работу с брейкпойнтами. Я постараюсь рассказать это максимально просто и без лишних деталей. Однако я пишу эту статью для тех читателей, который уже знают что такое брейкпойнты и умеют их использовать.

    Вы когда-нибудь задумывались, что происходит, когда вы нажимаете «Вставить брейкпойнт»? Или о том, как отладчик может добавлять брейкпойнты в код на лету и удалять их? О том, как работают брейкпойнты с условиями? О том, тормозят ли множественные установленные брейкпойнты выполнение программы?

    Сначала немного теории:

    Наверняка уже многие из вас сталкивались или слышали про ассемблерную инструкцию int 3 (_asm int 3 в C++). Именно эта инструкция — это основа всей системы брейкпойнтов.
    Когда процессор встречает эту инструкцию, то он инициирует отладочное исключение и передает его в обработчик прерываний операционной системы. А операционная система конвертирует его в софтварное исключение и инициирует его в том месте исполняемого файла, в котором было встречено это int 3. Тип этого исключения общеизвестен — это STATUS_BREAKPOINT (0x80000003).
    Если к процессу, инициировавшему это исключение, не присоединен отладчик, то этот процесс упадет. И вы увидите сообщения наподобии этих:


    Это возможно, если вы запускаете отладочную сборку или же сами оставили в своем коде int 3 в релизной сборке.

    Если же процесс работал под отладчиком (а обычно исключения STATUS_BREAKPOINT используются именно отладчиком), то это исключение передается в отладчик и дальше уже отладчик его обрабатывает.
    Также на уровне процессора поддерживаются брейкпойнты, срабатывающие на обращение к области памяти (может отлавливаться чтение, запись или исполнение кода). Таких брейкпойнтов может быть не более четырех. Они работают по другой схеме и глобальны для всей системы в целом, а не только для отлаживаемого приложения. Я на их работе подробно останавливаться не буду, а желающие могут погуглить про регистры DR0-DR7.

    Теперь практика:

    Когда вы ставите брейкпойнт в отладчике, то происходит следующее:
    Отладчик переводит область памяти, куда вы поставили брейкпойнт, в режим read-write (по умолчанию область памяти с исполняемым кодом read only), чтобы можно было менять там код на лету. Затем отладчик заменяет ассемблерную инструкцию в месте, куда вы поставили брейкпойнт, на int 3, а саму эту замененную инструкцию запоминает у себя в памяти.
    При этом всегда, когда вы просматриваете ассемблерный код в отладчике, он заменяет эти int 3 на реальные инструкции, но на самом деле там int 3, скрытые от ваших глаз.
    Также отладчик всегда заменяет все int 3 обратно на реальные инструкции, когда процесс останавливается на брейкпойнте и управление передается пользователю.

    Когда срабатывает брейкпойнт под отладчиком, то:
    Отладчик подменяет все int 3 (не только тот, который сработал, а все) на правильные инструкции, которые он запомнил при вставке этих int 3, и показывает точку брейкпойнта пользователю уже с нормальным кодом. Потом, когда пользователь запускает приложение выполняться дальше, то отладчик опять вставляет int 3 во все нужные места.
    Если брейкпойнт с условием, то при его срабатывании отладчик сначала проверяет условие и только при выполнении условия делает всю работу, как при обычном брейкпойнте. Если же условие не сработало, то отладчик выполняет запомненную команду, замененную на int 3, а потом продолжает выполнение с инструкции после int 3.

    Когда вы удаляете брейкпойнт, то:
    Отладчик просто заменяет вставленный int 3 обратно на нужную команду и забывает про этот брейкпойнт.

    Выводы, которые можно сделать из всего вышесказанного:

    Тормозят ли брейкпойнты, если их много?
    Нет, если они без условий. Простой брейкпойнт не требует дополнительных ресурсов отладчика или отлаживаемого процесса — это просто инструкция int 3. Даже если их миллион, но они не срабатывают, то это ни на милисекунду не замедлит выполнение программы.
    Но если установить брейкпойнт с условием, то даже один может замедлить программу в разы, если он стоит в часто вызываемом месте, так как в каждом таком брейкпойнте будет вызываться прерывание, потом вызываться исключение, передаваться в отладчик, который будет проверять условие, подменять команды и возвращать выполнение обратно в место брейкпойнта.
    Брейкпойнты на память также не тормозят, т.к. они поддерживаются на уровне процессора.

    Также надо учесть, что когда вы запускаете приложение под отладчиком, то в момент запуска он будет заменять на int 3 все инструкции в местах брейкпойнтов. И, если их очень много, это может занять долгое время (Например, отладчик MS Visual Studio 2005 при установке брейкпойнта в большом проекте (C++) в частоиспользуемую шаблонную функцию, например std::vector::operator[], иногда подвисает на минуту).

    P.S.:
    Все, что я тут написал, не касается брейкпойнтов в интерпретируемых языках программирования — я не знаю точно, как они там работают. Там за все отвечает интерпретатор и схема работы брейкпойнтов в нем может быть любой теоретически. Это же касается кода, исполняющегося под виртуальными машинами.
    P.S.2:
    Я специально писал все термины (брейкпойнт, отладчик, упадёт и т.п.) по-русски, чтобы не перемешивать английский и русский текст и чтобы было проще читать. Также я специально назвал точку останова брейкпойнтом, т.к. мне так кажется правильнее.

    Test: 193784457

    Средняя зарплата в IT

    120 000 ₽/мес.
    Средняя зарплата по всем IT-специализациям на основании 3 808 анкет, за 1-ое пол. 2021 года Узнать свою зарплату
    Реклама
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее

    Комментарии 69

      +3
      Я брейкпоинты всегда использовал в отладке, как и пошаговое выполнение, когда писал олимпиадные задачи…
      С того времени как начал писать под веб о них забыл :)
        +1
        Да, у каждой задачи — свои методы решения.
        Я сейчас тоже не так часто использую отладчик, т.к. разрабатываемый продукт работает на уровне ядра и с сотнями потоков, которые нельзя прерывать.

        Но ведь есть еще всякие небольшие домашние проектики или на работе тулзы — их приходится и поотлаживать по старинке :)
          +3
          Под веб отладчики таки тоже есть.
            0
            а я вот раньше писал много всякого винапишного и 3-дешного, на delphi и с++, под час, при помощи отладчика было удобнее сам алгоритм писать.

            А теперь пишу на PHP и никак не заставил себя настроить отладчик в eclipse… недавно прикрутил firebug к своему фреймворку… жить стало лучше (особенно AJAX), но это всё не то… сейчас вот сделаю над собой усилие и попробую таки прикрутить нормальный…
              0
              Рекомендую Zend Debugger. XDebug у меня часто ронял Apache.
              0
              > С того времени как начал писать под веб о них забыл :)

              А зря… удаленный дебаг какого-нибудь приложения под томкатом или JBoss экономит кучу времени… Даже если ты пишешь plain html страницы, то можно дебажить javascript (той же MS Visual Studio, например)
                0
                JS и все остальное, что касается верстки делает Firebug, но все же это не та отладка.
                И вообще, лучше писать без ошибок, чем потом отлаживать ^_^
                  0
                  «И вообще, лучше писать без ошибок, чем потом отлаживать ^_^»
                  я б вам душу продал если б вы научили меня так (:
                    0
                    Ну, не всегда получается, но хорошо обдумывая, анализируя, построив алгоритм в голове и потом написав его, можно зделать меньше ошибок, особенно тех, которые нужно искать отладчиком.

                    А вообще говорят «Если код запустился с первой компиляции — выкиньте компилятор, так не бывает» (-:
              +2
              недавно пытался объяснить знакомому про bp. не вышло.
              у вас отлично получается, продолжайте в том же духе. спасибо.
                +2
                Еще можно упомянуть, что опкод int3 занимает в памяти ровно один байт (CCh), а опкоды прерываний с другими номерами — два байта (CD xx). Это удобно, т.к. отладчику нужно запоминать/заменять только один первый байт оригинальной команды.
                  +2
                  Можно было бы, но я старался написать максимально просто и не перегрузить лишней информацией.
                  А 1 или 2 байта — это не так уж и важно для понимания сути процесса.
                    +9
                    int3 занимает один байт для того, чтобы можно было им заменять однобайтные команды. Если бы int3 занимал два байта и им заменили однобайтную команду, он бы затёр первый байт следующей команды, что сломало бы все переходы на эту вторую команду (так как переход осуществлялся бы в середину команды int3).
                      +1
                      Точно. Век живи — век учись)
                        0
                        Какая разница, каким числом байт затирать код? Одного бита достаточно.
                          0
                          Ну то есть какой смысл переходить к следующей команде, если текущая затерта?
                            0
                            Поразмыслил.
                            Я предположил(неверно прочел), что после выполнения отладочного прерывания управление возвращается восстановленной команде. Тогда нет разницы, какой длины была затерающая команда. Но тогда совершенно не ясно, как снова вернуть точку останова и как избежать ветвлений на сломанную команду, да.
                            А в статье по-русски написано, что обработчик сам выполняет затертую инструкцию и переходит к следующей за int 3.
                            Вероятно, если затерта была многобайтная команда, int 3 дополняется nop; ами, да? И на них возвращается управление.
                              +1
                              Пусть есть такой код по адресу скажем 100:
                              X1 Y1 Y2 Y3

                              X1 — первая команда, Y? — вторая.

                              Пусть int3 занимает два байта. Тогда если поставить брейкпоинт по адресу 100, получим:
                              Z1 Z2 Y2 Y3

                              Если в коде были переходы на адрес 101, то они сейчас сломаны, потому что переход будет осуществляться в середину команды int3 (это не вызовет выполнения команды int3, отладчик не сможет ничего подменить, будет выполнен какой-то мусор или вообще это будет считаться некорректным кодом).
                      +1
                      Дополнение к P.S.:

                      Может стоит еще добавить, что это не касается и компилируемых языков, но с другой средой выполнения (Java)? Там вроде бы используется Virtual Machine Debug (кажется так называлось).
                      • НЛО прилетело и опубликовало эту надпись здесь
                          0
                          Спасибо. Дописал в P.S.
                            0
                            да. вот меня заинтересовала ситуация с Java.
                            +1
                            Статья хорошая, спасибо.

                            Еще один момент, если не ошибаюсь, то отладчик VC++ при срабатывании брейкпоинта останавливает только один поток, в котором он сработал, все остальные потоки продолжают выполнятся. Также при пошаговом исполнении вы можете быть переброшены на другой брекпоинт, который сработал в другом потоке. В gdb останавливаются все потоки.

                            Вообще дебагер — расслабляет. Им очень легко не просто отлаживать, но и помогать себе при написании. К примеру написал кусок алгоритма, запустил и посмотрел как, что и где. Поскольку я сейчас часто пишу ядерный код, то приходится часто напрягатся и выверять каждую строку кода, иначе будет «приплыли» :)
                              0
                              Если бы он останавливал только 1 поток, то было бы очень много проблем — как уследить за целостностью данных? Надо все время пересчитывать значения переменных и обновлять их и т.п. Так что даже судя по этим возможным проблемам можно утверждать, что он все потоки останавливает :)
                                +1
                                Практика показывает, что VS2005 останавливает всё же один поток. Не знаю, как в 2008 версии.
                                  0
                                  Мне не очень хочется писать тестовое приложение, т.к. я уверен, что он останавливает все потоки.
                                  Но если вы настаиваете, то могу написать и проверить. Или сами проверьте :)
                              0
                              Спасибо, было интересно. Может быть напишете еще про аппаратную отладку?
                                0
                                Я никогда не отлаживал аппаратуру, так что знаю про это мало.
                                +1
                                >> Когда процессор встречает эту инструкцию, то он инициирует хардварное прерывание и передает его в обработчик хардварных прерываний операционной системы.

                                Это прерывание как раз программное, ты ведь его в своей программе сгенерировал. Кроме int 3 (оно обозначается #BP) существует ещё отладочное прерывание int 1 (#DB), но его обработчик можно переназначить, чем пользуются некоторые защиты(StarForce) или отладчики (Syser, SoftIce).
                                  –3
                                  int 3 — это обычное аппаратное прерывание, а не программное. Программное — это throw в C++. Просто это прерывание конвертится ОС в программное.
                                    +1
                                    AFAIK синхронно вызываемые из кода прерывания всегда было принято называть программными. До тех пор, пока переключаться на вектор 3 код будет путем выполнения инструкции int 3 оно будет программным. Если вы подключите внешний аппаратный отладчик, который по своим соображениям сгенерирует это прерывание, его назовут аппаратным.
                                    А throw это механизм совершенно другого уровня.
                                      –2
                                      Его называют аппаратным, т.к. это прерывание приходит в операционную систему из процессора — поэтому оно аппаратное.
                                        0
                                        А как оно «пришло в процессор» в вашем восприятии предмета не учитывается?
                                          0
                                          Это не мое восприятие предмета — это то, как пишут в книгах. Я своих терминов не вводил :)
                                            0
                                            Интересно узнать, что это за книги. Там за вас ввели неверное определение. Гляньте википедию, там указано более расхожее :)
                                              0
                                              Что за книги такие интересные? И как конкретно они определяют прерывания
                                              1. программные
                                              2. внутренние
                                              3. аппаратные
                                              ?
                                              0
                                              Это очень спорный вопрос. Я читал и сам считаю, что аппаратное прерывание — это IRQ, которое пришло от какого-нибудь девайса, APIC контроллера. int3 — программное, во-первых потому что isr хендл на него не повесить. Также посмотрите в исходники той же Mac OS X. Там int3 обслуживает тот же trap хендлер, который обслуживает остальные инструкции, как-то вызов rdmsr или in/out из юзермодного кода, все идет в один и тот же kernel_trap.
                                              0
                                              Любое прерывание «приходит в систему» из процессора. Это не критерий.
                                            +1
                                            Тьфу, я в своём комменте выше ошибся. int 3 это программное ИСКЛЮЧЕНИЕ, а не прерывание.

                                            Под исключения в архитектурах x86 отведены первые 20 записей в IDT(interrupt descriptor table).

                                            Intel® 64 and IA-32 Architectures Software Developer's Manual, Volume 1:

                                            The Processor provides two mechanisms for interrrupting programm execution, interrupts and exceptions:

                                            — An interrupt is a asynchronous event that is typically triggered by an I/O device.
                                            — An exception is as synchronous event that is generated when the processor detects one or more predefined conditions while execution instruction. The IA-32 architecture specifies three classes of exceptions: faults, traps and aborts.

                                            int3/int1 — отладочные исключения, throw в С++ — программное исключение. Нажатие кнопки мышки — аппаратное прерывание.
                                              0
                                              >>int3/int1 — отладочные исключения, throw в С++ — программное исключение. Нажатие кнопки мышки — аппаратное прерывание.

                                              Да, все правильно. Но отладочные исключения работают посредством аппаратных прерываний :)
                                                0
                                                Я ведь привёл определение. Это два разных термина. Механизм один, а терминология разная. Поэтому если говорить, а уж тем более писать статью, про int3, то его надо называть так, как принято, а не как захочется.
                                                  0
                                                  Напишите свою статью, причем так, чтобы было просто и понятно — тогда имеет смысл давать советы что и как писать :)
                                                  Я не претендую на научность статьи, вполне мог что-то напутать или не проверить термины, т.к. писал без проверки. Но моя основная идея — показать на верхнем уровне, как оно работает без лишних деталей.
                                                    0
                                                    Да ладно вам, не обижайтесь :)

                                                    Я привёл отрывок из мануалов от интела. На них стоит ровняться. Вопрос терминологии достаточно важен, особенно, если вы пишите для новичков. Всем хочется, чтобы новая информация была достоверной, в том числе соответствовала общепринятой терминологии.
                                                      0
                                                      Я не обижаюсь :)
                                                      Исправил это место в статье — теперь лучше?
                                                  0
                                                  >> Но отладочные исключения работают посредством аппаратных прерываний :)

                                                  Ничего подобного. Я извиняюсь, но если вы это говорите, то у вас отсутствует понимание того, что вы пишите.
                                                  Отладочные исключения в Windows работают не по средствам аппаратных прерываний, а благодаря механизму структурной обработки исключений(SEH) на уровне системы и аппаратному механизму контроля исполнения программы архитектуры x86-64.

                                                  Генерируется исключение, определяется вектор и процедура обработки по IDT. Управление передаётся системному коду уровня ядра(диспетчеру исключений), он определяет тип в каком потоке было сгенерировано исключение, извлекает TEB из регистра FS[0] и начинает обработку исключения в поисках подходящего обработчика(более подробно у Руссиновича и Питрека).
                                                  Где тут аппаратные прерывания?
                                                    0
                                                    Цитата из Advanced Windows Debugging (Mario Hewardt). Глава 3. Debuggers uncovered. How breakpoints work (стр. 168):
                                                    In response to the STATUS_BREAKPOINT exception, the processor executes the interrupt handler registered for the interrupt vector 3.
                                                    и т.д. там еще много текста про векторы прерываний.

                                                    Я не хочу развивать эту техническую тему дальше — статья написана специально предельно просто и не вдается в подробности, т.к. они большинству не нужны. Аппаратные прерывания или аппаратные исключения — это по большому счету неважно для понимания сути процесса.
                                                    Так что спасибо за детали из Руссиновича, но я опирался на книгу Хьюварта, которую, кстати, тоже Руссинович рецензировал.
                                                      0
                                                      Не увидел в отрывке выше «hardware interrupt», поэтому не понял к чему вы его привели. Там как раз говорится про исключение. А «interrupt vector» потому что таблица из которой он берётся называется interrupt descriptor table.
                                                        0
                                                        Да, с «аппаратным прерыванием» возможно я был неправ и действительно запутался в терминах — не хочу перечитывать заново литературу и уточнять. Хотя «the processor executes the interrupt handler „ для меня звучит, как указание на то, что происходит прерывание, по крайней мере вызывается обработчик прерывания. Но не в этом суть.
                                                        Через пару недель иду на семинар Соломона — бывшего партнера Руссиновича по windows internals. Надеюсь там это будет детально раскрыто.
                                            0
                                            увлекался исследованием защиты программ. Да и сейчас ещё многое помню. Увлекательный процесс, скажу я вам…
                                              0
                                              Эмс. Неужели Microsoft такая отсталая система, что ничего не знает о debug-регистрах? Чего-то плохо в это верится. Если я не ошибаюсь, то точки останова там можно было ставить и на доступ к данным, что, по идее, как раз и говорит о том, что MS умеет пользоваться этими регистрами… Вобщем, что-то тут не сходится.

                                              int 3, они, конечно, должны были бы оставить для совместимости, но вряд ли это — основной механизм отладки.
                                                –4
                                                Про регистры на доступ к памяти я немного написал в статье. Конечно, они их используют, но это не основной механизм работы.
                                                  0
                                                  Вы имеете ввиду отладочные регистры DRx? Конечно знает, но причём здесь система? Речь об отладчиках и отлапдочных средствах. Debug API windows позволяют с ними работать. Ну а собственно это ведь не системный механизм, а процессорный.
                                                    0
                                                    Для отладки приложения, написанного в MS VS имеющегося int 3 вполне достаточно. Другое дело, если вы хотите проникнуть в недра чужой программы, вдобавок еще защищенной чем-либо, тут без отладочных регистров будет труднее, чем с ними. Хотя бы потому, что int 3 модифицирует код. Про такие вещи очень хорошо написано у Криса Касперски в книге «Техника отладки программ без исходных текстов» — живой язык, масса примеров и аналогий, для понимания не требуется заранее обладать навыками, которым там учат.
                                                    0
                                                    полезная статья.

                                                    вот у меня вопрос возник. почему условные брейкпоинты работают так как выговорите? не легче просто вызывать int 3 по нужному условию, т.е. воспользоваться самим языком, а не передавать в отладчик?
                                                      0
                                                      все, сам понял. ступил.
                                                        0
                                                        Это бы сделало невозможным установку условия во время выполнения без перекомпановки (linking'а) кода. А для этого его пришлось бы перезапускать. Поэтому условные ТО такие медленные.
                                                        +1
                                                        ; Когда вы удаляете брейкпойнт, то:
                                                        Отладчик просто заменяет вставленный int 3 обратно на нужную команду и забывает про этот брейкпойнт
                                                        ;

                                                        Как-то сложно получается. Гораздо проще понавставлять перед каждым оператором nop, который при необходимости легко заменяется на int 3.
                                                          0
                                                          И иметь проблемы с производительностью и размером ехе файла?
                                                          Напиминаю, что брейкпойнты можно и в релизных сборках ставить.
                                                            0
                                                            Вспоминаю я многомесячную отладку железки, когда добавление одного NOPа приводило к полному исчезновению багов. Причем NOP ставился в участок кода, который управления никогда не получал! Размещение блоково кода менялось и начиналось… Под винду с многопоточными приложениями, если они криво написаны, то же самое будет — поставил NOP и работать начинает иначе. Или не работает дебажная сборка, а релизная пашет. Лишние нопы лучше не ставить :-)
                                                          • НЛО прилетело и опубликовало эту надпись здесь
                                                              +1
                                                              Есть особенность использования бряков в самомодифицирующемся коде: если поставить бряку (не хардварную) на код, который будет изменен, бряка с большой долей вероятности не сработатет. Думаю, это из-за того, что выполняющийся код заменит INT3 на то, что ему надо. Хардварные лучше, но их мало :-(
                                                                +1
                                                                Кстати, написал бы про это статью — было бы очень интересно почитать про методы борьбы с таким кодом. Как вы узнаете, как такой процесс работает и что делает?
                                                                Кстати, у вас в drWeb система HIPS есть? Или эвристический анализ файла с поиском внутри всяких ссылок на левые сайты и т.п.?
                                                                  +1
                                                                  Да, тема интересная. Я вот все хочу стащить с работы десяток разных вирусных пакеров да написать, как авторы изголяются. И про антиоладку на SEH основанную, и чтоже все-таки делать, чтобы их вскрыть :-) Самомодифицирующийся код я встречал только в упаковщиках, распакованные данные так не делают. Либо же я не понял, что код сам себя модифицировал. А пакеры видно либо в Hiew либо же в IDA с первых строк. Методики распаковки я для себя уже вывел :-)

                                                                  HIPS — это en.wikipedia.org/wiki/Intrusion-prevention_system? Кажется нет. Чтобы посмотреть, куда троянчег ломится, достаточно и ethereal, в общем. Надо бы, конечно, сделать сборку поудобнее, да что-то руки не доходят.
                                                                    +1
                                                                    HIPS — это мощная фича. Она позволяет находить новые вирусы по их вредоносному поведению. Например, если программа пишет себя в автозагрузку, да шлет что-то вовне, да пытается устанавливать хуки — hips ее заблочит и спросит пользователя — а уверен ли он, что это не вирус?
                                                                    Так можно ловить даже новые вирусы… теоретически, сам понимаешь :)
                                                                      0
                                                                      А, кажется понял, про что ты :-) Обычно термин «поведенческий блокиратор» слышу :-) Я не очень вкурсе нововведений в 5-й версии (которая до НГ должна выйти), которые не касаются непосредственно баз.
                                                                      Главный минус такой штуки, как мне кажется, — довольно большое количество ложных срабатываний. Соответственно, окончательные решения будет принимать пользователь, который далеко не всегда понимает что и как.
                                                                        0
                                                                        Да, выбор за пользователем в спорных случаях.
                                                                        Там так: есть у каждого процесса показатель его «опасности» — число от 0 до 100, например.
                                                                        Также есть 2 числа — minDanger (например 30) и maxDanger (например 60). Соответственно если опасность процесса меньше minDanger, то HIPS его игнорирует. Если от minDanger до maxDanger, то спрашивает пользователя. А если больше maxDanger, то сразу блочит без вопросов.
                                                                        Так что самые вредоносные сразу блочатся без вопросов, но в некоторых случаях спрашивается совет у пользователя.
                                                                        Конечно, в UI можно всегда изменить решение и разрешить или заблокировать что-то.
                                                                0
                                                                Не понятен только один пункт: тормозят ли брейкпоинты.

                                                                Как они могут тормозить, если они останавливают выполнение программы. Но если отбросить этот момент, то думаю, что даже брейкпоинты без условий замедляли бы выполнение программы(это мое имхо исходя из скудных знаний асма на x86 и микроконтроллерах).
                                                                  0
                                                                  Имелось в виду конечно, тормозят ли брейкпойнты, которые не срабатывают. Если сработал — то тут уже не до тормозов, все стоит.
                                                                  А насчет второго — как брекпойнт может замедлить программу, если это просто инструкция в нужном месте, которое не вызывается?
                                                                  0
                                                                  Если сильно придираться, можно сказать что процессор некогда не передает отладочное исключение в обработчик прерываний операционной системы, он передает его по адресу указанному в векторе прерываний, который в свою очередь любая уважающая себя ОСь переписывает… но о самой ОС процессору не как не извесно)

                                                                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                  Самое читаемое