Это старая версия (1.4) PtraceTuto.

Содержание

Принципы работы Отладчиков

Часто для того, чтобы разобраться почему код работает не так, программист прибегает к помощи отладчиков, однако, то как они устроены и каким образом действуют, известно далеко не всем. В этой статье будет дано краткое описание механизма отладки, который используется операционной системой Linux и приведён короткий пример его использования.

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

Типы Отладчиков:

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

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

Перечислим основные функции, необходимые отладчику:

  • возможность стартовать и останавливать процесс.
  • возможность пошагового исполнения кода.
  • возможность читать и писать в произвольную область памяти.
  • чтение и изменение содержимого регистров процессора.

Системный вызов ptrace(2)

В OC Linux весь отладочный функционал доступен с использованием системного вызова ptrace(2).

интерфейс системного вызова:


long ptrace(enum __ptrace_request request , pid_t pid , void ∗addr , void ∗data);

Аргумент request определяет тип операции: будет ли это попытка начать отладку процесса, или это будет запрос данных по какому-либо адресу. Все прочие аргументы являются опциональными и зависят от значения request.

Начать отладку процесса можно двумя способами:

  • C помощью запроса PTRACE_TRACEME
текущий процесс будет отлаживаться его родителем. Любой сигнал, полученный текущим процессом, вызовет его остановку, а родительский процесс может быть оповещён об этом сигналом SIGCHLD. Затем родитель при помощи системного вызова wait(2) или подобного узнаёт идентификатор остановленного процесса. Заметим, что для этого типа запроса все остальные аргументы игнорируются.
  • С помощью запроса PTRACE_ATTACH

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