Как работает отладчик?

Мне интересно, как работает отладчик? Particulary - тот, который может быть "прикреплен" к уже запущенному исполняемому файлу. Я понимаю, что компилятор переводит код на машинный язык, но тогда как отладчик "знает", к чему он привязан?

Ответ 1

Сведения о том, как работает отладчик, будут зависеть от того, что вы отлаживаете, и от какой ОС. Для собственной отладки в Windows вы можете найти некоторые сведения о MSDN: API отладки Win32.

Пользователь сообщает отладчику, к которому подключается процесс, по имени или по идентификатору процесса. Если это имя, отладчик будет искать идентификатор процесса и инициировать сеанс отладки через системный вызов; под Windows это будет DebugActiveProcess.

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

Отладчик способен читать и записывать виртуальную память целевого процесса и даже корректировать свои значения регистра через API, предоставляемые ОС. См. Список функций отладки для Windows.

Отладчик может использовать информацию из файлов символов для перевода с адресов на имена переменных и местоположения в исходном коде. Информация о файле символа представляет собой отдельный набор API и не является основной частью ОС как таковой. В Windows это через Отладочный интерфейс доступа к SDK.

Если вы отлаживаете управляемую среду (.NET, Java и т.д.), процесс, как правило, будет похож, но детали разные, поскольку среда виртуальной машины предоставляет API отладки, а не базовую ОС.

Ответ 2

Как я понимаю:

Для контрольных точек программного обеспечения на x86 отладчик заменяет первый байт команды на CC (int3). Это делается с помощью WriteProcessMemory в Windows. Когда процессор получает эту команду и выполняет int3, это заставляет ЦП генерировать исключение отладки. ОС получает это прерывание, понимает, что процесс отлаживается, и уведомляет процесс отладчика о том, что точка останова была удалена.

После того, как точка останова будет удалена, и процесс будет остановлен, отладчик будет выглядеть в списке контрольных точек и заменяет CC байтом, который был там первоначально. Отладчик устанавливает TF, флаг Trap в EFLAGS (путем изменения CONTEXT) и продолжает процесс. Флаг Trap заставляет CPU автоматически генерировать одношаговое исключение (INT 1) в следующей инструкции.

Когда отлаживаемый процесс останавливается в следующий раз, отладчик снова заменяет первый байт команды точки останова на CC, и процесс продолжается.

Я не уверен, что это именно то, как это реализовано всеми отладчиками, но я написал программу Win32, которая управляет отладкой себя с использованием этого механизма. Полностью бесполезный, но образовательный.

Ответ 3

В Linux отладка процесса начинается с системного вызова ptrace (2). В этой статье есть отличный учебник по использованию ptrace для реализации некоторых простых конструкций отладки.

Ответ 4

Если вы работаете в операционной системе Windows, хорошим ресурсом для этого будет "Отладка приложений для Microsoft.NET и Microsoft Windows" Джона Роббинса:

(или даже более старая версия: "Отладка приложений")

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

Поскольку я не знаком с деталями отладки Unix/Linux, этот материал может вообще не относиться к другим ОС. Но я предполагаю, что в качестве введения в очень сложную тему концепции - если не детали и API - должны "переноситься" на большинство любых ОС.

Ответ 5

Другим ценным источником для понимания отладки является руководство по процессору Intel (архитектуры Intel® 64 и IA-32 Руководство для разработчиков программного обеспечения). В томе 3A, глава 16, он представил аппаратную поддержку отладки, такую ​​как специальные исключения и аппаратные отладочные регистры. Ниже приведена следующая глава:

T (ловушка) флаг, TSS - генерирует исключение отладки (#DB), когда попытка чтобы переключиться на задачу с флагом T, установленным в его TSS.

Я не уверен, использует ли Window или Linux этот флаг или нет, но очень интересно прочитать эту главу.

Надеюсь, это поможет кому-то.

Ответ 6

Я понимаю, что при компиляции приложения или DLL файла все, что он компилирует, содержит символы, представляющие функции и переменные.

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

Ответ 7

Я думаю, что здесь есть два основных вопроса:

1. Как отладчик знает, что произошло исключение?

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

enter image description here


2. Как отладчик знает, как остановиться на точке останова?

Упрощенный ответ: когда вы ставите точку останова в программе, отладчик заменяет ваш код в этой точке инструкцией int3, которая является программным прерыванием. В результате программа приостанавливается и вызывается отладчик.