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



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

643   6  

6 ответов:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Еще одним ценным источником для понимания отладки является руководство Intel CPU manual (архитектуры Intel® 64 и IA-32 Руководство разработчика программного обеспечения). В томе 3А, Глава 16, он представил аппаратную поддержку отладки, такую как специальные исключения и аппаратные отладочные регистры. Из этой главы следует следующее:

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

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

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

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

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

Comments

    Ничего не найдено.