Синтаксис расширенных точек прерывания и позиционные точки прерывания
Перед обсуждением возможностей расширенных точек прерывания потратим немного времени на рассмотрение их синтаксиса. Это важно, потому что в диалоговом окне Breakpoints показан список описателей вставленных в код точек прерывания в соответствующем формате. К счастью, синтаксис таких описателей довольно прост. В листинге 5-1 (раздел "Точки прерывания глобальных выражений и условные точки прерывания" данной главы) приведена программа AdvancedBP, которая демонстрирует каждый тип расширенных точек прерывания. Проект этой программы находится на сопровождающем компакт-диске, его можно открыть в Visual Studio и обращаться к нему при работе с этим разделом.
Синтаксис описателя расширенной точки прерывания состоит из двух частей. В первой части размещается набор строк в определенном формате (контекст), а во второй — условие, задающее позицию точки прерывания в исходном коде (обычно номер строки), а также выражение, переменную или Windows-сообщение, с которыми связывается это прерывание. Контекст можно представлять себе примерно как область действия (scope) идентификатора переменной при программировании. Контекст указывает отладчику точное место расположения точки прерывания.
В полном формате контекста перечисляются (через запятую в указанном порядке) имена функции, исходного файла и двоичного модуля:
{[функция], [исходный файл], [двоичный модуль]}
Загрузочный или исполняемый модуль приложения.. Все элементы контекста не обязательны. При пропусках элементов запятые сохраняются. — Пер.
Чтобы установить точку прерывания, нужно определить достаточное количество контекстной информации. В простой позиционной точке прерывания отладчику надо только имя исходного файла. Читателю, вероятно, знаком простой формат позиционной точки прерывания в диалоговом окне Breakpoints. Если установить такую точку прерывания на строке, например, 20 файла TEST.CPP, то в диалоговом окне Breakpoints будет описана так:
{,TEST.CPP,}.20
См. список Breakpoints в нижней части окна Breakpoints, открываемого командой Edit|Breakpoints.
— Пер.
Возможность указать контекст для позиционной точки прерывания позволяет решать особенно неприятный тип проблем отладки. Рассмотрим следующий случай: исходный файл с диагностической функцией CheckMyMem используется двумя библиотеками динамической компоновки — A.DLL и B.DLL и включен в них с помощью статической компоновки. Если соблюдаются принципы профилактического программирования, то имеют место многократные вызовы этой функции из обеих DLL. Однако только при вызове из В.DLL часто происходят случайные аварийные остановы. Если установить стандартную позиционную точку прерывания в исходном коде функции checkMyMem (ее синтаксис в этом случае выглядит как {,CHECKMYMEM.CPP, } .27), то она будет срабатывать в обеих DLL, даже если вы хотите, чтобы вызовы делались только из В.DLL. Если нужно, чтобы точка прерывания срабатывала только в B.DLL, то придется использовать контекст точки прерывания в следующей форме: {, CHECKMYMEM.CPP, в.DLL}.27. Синтаксис контекста можно ввести с клавиатуры непосредственно в редактируемое поле Break At на вкладке Location диалогового окна Breakpoints (открываемого командой Edit|Breakpoints или нажатием клавиш <Alt>+ +<F9>) отладчика Visual C++; однако легче использовать диалоговое окно Advanced Breakpoint, показанное на рис. 5.1. Для его открытия нажмите кнопку со стрелкой справа от редактируемого поля Break at (в панели Breakpoints), чтобы раскрыть меню. В этом меню выберите пункт Advanced и затем в поля группы Context окна Advanced Breakpoint введите информацию для контекстной части синтаксиса точки прерывания.
Реальная мощь расширенных точек прерывания сосредоточена во второй части их синтаксиса, где указывается расположение (позиция) точки прерывания в исходном коде, выражение, переменная или Windows-сообщение, связанные с точкой прерывания. Синтаксис позиционных точек прерывания довольно прост -г- после фигурных скобок контекста указывается десятичный номер строки, на которой располагается точка прерывания в исходном коде (номер отделяется от контекста десятичной точкой).Однако можно выполнять прерывание с помощью других типов позиций. Например, если необходимо выполнить прерывание по известному абсолютному адресу (а не по номеру строки), то нужно просто ввести этот адрес в поле Break at диалогового окна Breakpoints. Например, при написании данного раздела использовалась упомянутая выше программа AdvancedBP. Точка входа данного приложения (mainCRTStartup) расположена по адресу 0x401210 — это и есть абсолютный адрес, который задавался для точки прерывания. Напомним, что при вводе шестнадцатеричного адреса нужно указывать префикс Ох.