Ptrace один шаг в ядре из контекста процесса? - PullRequest
2 голосов
/ 21 октября 2011

Мне было интересно, что произойдет, если из ядра (в данном случае Linux) вы вызовете ptrace_request с PTRACE_SINGLESTEP в контексте процесса (системный вызов, ошибка страницы и т. Д.).Будет ли он одним шагом инструкции пространства пользователя или инструкции пространства ядра.Я понимаю, что ptrace может выполнять только одношаговые пользовательские инструкции, поэтому мне любопытно, как это будет происходить.

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

Это происходит потому, что task_struct для процесса (еслипрервано) по-прежнему будет указывать на обработчик пространства ядра IIRC, так что обход одного шага с ptrace будет обходить это и будет ли выполнять правильные инструкции в пространстве пользователя или просто не будет делать это вообще?

Ответы [ 2 ]

1 голос
/ 08 ноября 2011

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

Я рекомендую вам взглянуть на arch / x86 / kernel / ptrace.c, чтобы понять, как на самом деле работает один шаг.Одношаговая инструкция фактически эмулируется ядром, в IIRC нет аппаратной поддержки для этого.

0 голосов
/ 31 января 2012

Чтобы понять ответ на ваш вопрос, вам необходимо понять аппаратное обеспечение Intel.

Сначала мы начнем с самой простой инструкции (поскольку SINGLE_STEP переводит процессор Intel в режим одноступенчатого перехода и возвращается к обработчику прерываний после выполнения одной структуры):

мовл (eax), отлив

В соответствии с форматом Intel это означает получение значений внутри eax, обработку их как указателя памяти, доступ к памяти, получение 4-байтовых значений и копирование их в ebx.

Эта ОДНА инструкция по сборке - при выполнении в контексте ядра и пользователя будет иметь РАЗНОЕ поведение / значение.

Если в ядре таблица страниц ядра будет использоваться для доступа к памяти и копирования данных в ebx. В пользовательском процессе таблица пользователя будет использоваться (кстати, аппаратным обеспечением MMU) для чтения данных из памяти и копирования в ebx. Одинаковые значения в eax, но с разными значениями в регистре CR3 (что означает различный контекст процесса), будут запускать чтение различных частей памяти. Так что трассировка пользовательских программ в ядре, действительно, нелепа. Потому что вам нужно сделать переключение контекста (которое включало весь набор операций по сохранению и восстановлению регистров), выполненное до и после выполнения пользовательской инструкции - что означает эффективное выполнение 4 операций.

Как видите, я не ссылался ни на один API-интерфейс функций ядра, как вы упомянули. Общее концептуальное понимание на первом месте.

...