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

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

156 голосов
/ 19 октября 2008

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

Ответы [ 7 ]

89 голосов
/ 19 октября 2008

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

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

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

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

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

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

54 голосов
/ 13 февраля 2014

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

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

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

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

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

24 голосов
/ 20 октября 2008

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

10 голосов
/ 20 октября 2008

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

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

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

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

3 голосов
/ 02 марта 2011

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

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

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

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

1 голос
/ 19 октября 2008

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

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

0 голосов
/ 09 мая 2019

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

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

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

enter image description here


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

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

...