Операции Step Into, Step Over и Step Out
Теперь, после описания точек прерывания и символьных машин, можно объяснить, как отладчики реализуют три замечательные операции — Step Into, Step Over и Step Out. Они не реализованы в WDBG, потому что я хотел сконцентрироваться на основных частях отладчика. Эти функции работают в рамках двух специальных представлений1 отлаживаемой программы, которые позволяют отслеживать текущую выполняемую строку или команду.
Все эти операции (Step Into, Step Over и Step Out) работают с одноразовыми точками прерывания, которые, как вы помните из предыдущих разделов, являются точками прерывания, сбрасываемыми отладчиком после того, как они срабатывают. При обсуждении пункта меню Debug Break (см. выше) был рассмотрен другой случай, в котором отладчик использует одноразовые точки прерывания для остановки обработки.
Операция Step Into работает по-разному, в зависимости от того, на каком уровне выполняется отладка: на исходном или на уровне дизассемблирования. При отладке на исходном уровне отладчик должен ориентироваться на одноразовые точки прерывания, потому что одна строка языка высокого уровня переводится в одну или большее количество строк языка ассемблера. При переводе CPU в пошаговый режим будет происходить пошаговое выполнение индивидуальных машинных команд, а не строк исходного кода.
На исходном уровне отладчик знает, на какой исходной строке вы находитесь. Когда выполняется команда отладчика Step Into, то для нахождения адреса следующей выполняемой строки отладчик использует символьную машину. Отладчик выполнит частичное дизассемблирование по адресу следующей строки, чтобы видеть, является ли эта строка командой вызова. Если строка — команда вызова, то отладчик установит одноразовую точку прерывания на первом же адресе функции, которую собирается вызывать подчиненный отладчик. Если адрес следующий строки — не команда вызова, то отладчик там и устанавливает точку прерывания one-shot. Затем отладчик разблокирует подчиненный отладчик, чтобы тот выполнился до только что установленной точки прерывания.
Когда эта точка прерывания сработает, отладчик заменит код операции в точке ее размещения (в памяти) и освободит связанную с ней память. Если пользователь работает на уровне дизассемблирования, то реализовать Step Into намного легче, потому что отладчик будет просто переводить CPU в режим пошагового выполнения.
Операция Step Over похожа на Step Into в том, что отладчик должен отыскивать следующую строку в символьной машине и dsgjkyznm частичное дизассемблирование по адресу строки. Различие их в том, что для Step Over (если строка является вызовом) отладчик также будет устанавливать точку прерывания one-shot, но после инструкции вызова.
Операция Step Out, в некотором смысле, является самой простой из трех. Когда пользователь выбирает команду Step Out, отладчик проходит стек, чтобы найти адрес возврата для текущей функции и устанавливает по этому адресу точку прерывания one-shot.
Source view (представление в виде строк исходного кода) и disassembly view (представление в виде кодов дизассемблера в окне Disassembly). — Пер.
Обработка операций Step Into, Step Over и Step Out кажется довольно простой, но имеется одна особенность, которую следует рассмотреть. Что делать, если (в отладчике, создаваемом для управления этими операциями) уже установлены точки прерывания one-shot для этих операций, а перед ними срабатывает регулярная точка прерывания? Как разработчик отладчика, вы имеете две возможности. Первая — оставить только точки прерывания one-shot (чтобы только они и срабатывали). Другая возможность — удалять точки прерывания one-shot, когда отладчик уведомляет вас о том, что сработала регулярная точка прерывания. Отладчик Visual C++ использует последнюю возможность.