осуществление шаг за, карлик

Я работаю над отладчиком исходного кода. Отладочная информация доступна в формате elf. Как можно было бы реализовать «перешагнуть»? Проблема в «Point1», в любом случае я могу дождаться следующей строки исходного кода (читая ее из таблицы .debug_line).

Спасибо

if (a == 1)
 x = 1; //Point1
else if (a == 2)
 x = 1;

z = 1;

person User01    schedule 11.07.2010    source источник


Ответы (1)


Я не уверен, что полностью понял вопрос, но могу рассказать вам, как GDB реализует свою команду step.

Как только управление перешло к определенной единице компиляции, GDB считывает отладочную информацию этого CU; в частности, он считывает часть CU раздела .debug_line и строит таблицу, которая отображает адреса инструкций в позиции исходного кода.

Когда начинается step, GDB ищет исходное местоположение для текущего ПК. Затем он выполняет машинные инструкции, каждый раз просматривая исходное местоположение нового ПК, пока исходное местоположение не изменится. Когда исходное местоположение изменится, step завершится.

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

Чтобы понять, почему необходимо проверять идентификатор кадра, а также местоположение источника, рассмотрите пошаговый вызов следующей функции:

int fact(n) { if (n > 0) { return n * fact(n-1); } else return 1; }

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

fact (n=10) at recurse.c:4
(gdb) step
fact (n=9) at recurse.c:4
(gdb) step
fact (n=8) at recurse.c:4

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

Стоит немного подумать о том, как обрабатывать встроенные экземпляры функций (которые описаны в DWARF). Но это слишком много для этого вопроса.

Не для того, чтобы препятствовать экспериментам, но если бы я начинал проект отладчика, я бы хотел взглянуть на отладчик Apple, который находится в стадии разработки, lldb с открытым исходным кодом.

person Jim Blandy    schedule 30.07.2010