Когда я присоединяюсь к процессу, используя PTRACE_ATTACH, как мне узнать, находится ли трассировка в системном вызове или нет?
Когда вы присоединяетесь к процессу, используя PTRACE_ATTACH, трассировке отправляется сигнал STOP.
Сигнал STOP может вступить в силу при выполнении кода пользовательского пространства, при вводе системного вызова, при блокировке «медленного» системного вызова в ядре и при возврате в пользовательское пространство из системного вызова.
Исследуя указатель инструкций и инструкции вокруг указателя инструкций, вы обычно можете определить, выполнял ли процесс код пользовательского пространства, но это все.
Однако, поскольку точка останова является, по сути, случайной, вы можете дождаться остановки процесса, а затем пошагово каждый из его потоков, используя PTRACE_SINGLESTEP, пока указатель инструкции не изменится. Тогда вы знаете, что поток выполняет код пользовательского пространства.
В качестве альтернативы, если одиночный шаг приводит к тому, что поток блокируется в течение длительного времени, это означает, что поток выполняет медленный системный вызов, который блокирует.
Иными словами, если я перезапущу трассировку с помощью PTRACE_SYSCALL, как мне узнать, является ли следующий syscall-stop syscall-enter-stop или syscall-exit-stop?
Нет, если вы не знаете, в каком месте остановилась трассировка. Как я уже отмечал выше, это можно сделать, пошагово выполняя код, пока указатель инструкции не изменится.