2009-08-17 6 views
2

Я наткнулся на очень интересную проблему, когда функция (должна иметь дело с буфером Windows) в моем приложении работает только правильно, когда точка останова попадает внутрь функции. Мне стало интересно, что именно делает отладчик (VS2008, C++), когда он достигает точки останова?Что именно делает отладчик?

+1

Это останавливается ... ;-) –

+1

не совсем ответ, который вы ищете, но я не мог удержаться: «Отладка - это как причуда - это не так плохо, когда это ваш собственный код». – vehomzzz

ответ

2

http://en.wikipedia.org/wiki/Debugger

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

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

Я бы рекомендовал прочитать статью в Википедии для получения дополнительной информации.

3

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

1

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

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

Отладка возможна, потому что компилятор вставляет в ваш исполняемый файл отладочную информацию (такую ​​как имена функций, имена переменных и т. Д.). Его можно не включать в эту информацию.

2

Отладчик просто останавливает выполнение вашей программы, когда она достигает точки останова. Если ваша программа работает нормально, когда она попадает на точку останова, но не работает без точки останова, это указывает на то, что в вашем коде есть состояние гонки или другая проблема с потоками. Точка прерывания останавливает выполнение вашего кода, возможно, позволяет другим процессам нормально функционировать?

4

Возможно, это проблема синхронизации времени и синхронизации. Есть ли в вашей программе мультимедиа или многопоточность?

6

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

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

+0

Состояние гонки было моей первой мыслью тоже. – luke

7

без прямого ответа на ваш вопрос (так как я подозреваю, что внутренняя работа отладчика не может быть действительно проблема), я предлагаю две возможные причины, это может случиться, что я видел раньше:

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

Во-вторых, Visual Studio исторически (я не уверен в 2008) перераспределенной памяти при работе в режиме отладки. Так, например, если у вас есть выделенный массив из int[10], он должен по праву получить 40 байт памяти, но Visual Studio может дать ему 44 или более, предположительно, если у вас есть ошибка за пределами границ. Конечно, если у вас есть ошибка вне пределов, это избыточное распределение может заставить его работать в любом случае.

+3

По крайней мере, с 2008 года выделенная оперативная память используется для канарейков. Если ваш код переполняет массив и взрывает канарейку, отладчик останавливается и предлагает вам, чтобы вы повредили стек.Перераспределение - обнаружение ошибок, а не их скрытие;) –

+1

Обратите внимание, что это ловит записи, не связанные с пересылкой, но не выходящие из нее. В равной степени они ошибочны, но гораздо сложнее отлаживать. – MSalters

1

Отладчики иногда меняют способ работы программы для правильной работы.

Я не уверен в Visual Studio, но, например, в Eclipse. Java-классы не загружаются одинаково при запуске внутри среды IDE и при запуске за ее пределами.

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

Дополнительная информация о программе может помочь.

0

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

  • инициализирует выделенную память шаблона (0xCDCDCDCD приходит на ум, но я могу ошибаться)
  • она заполняет освободила память с другим рисунком
  • это overallocates распределения кучи (как предыдущий ответ упомянутым)

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

Две полезных приемов:

  1. Использование PageHeap поймать доступ к памяти после окончания выделенных блоков
  2. Сложения с помощью/RTCsu (старые Visual C++ компиляторов:/GX) переключатель. Это приведет к инициализации памяти для всех ваших локальных переменных ненулевым битовым шаблоном, а также вызовет ошибку времени выполнения при доступе к унифицированной локальной переменной.
+1

На самом деле, изменения в управлении кучей исходят из отладочной версии CRT, а не из самого отладчика. См. Http://msdn.microsoft.com/en-us/library/e5ewb1h3(VS.80).aspx –

Смежные вопросы