После подключения к процессу, как проверить, находится ли трассировка в системном вызове? - PullRequest
0 голосов
/ 28 августа 2018

Согласно странице руководства по ptrace :

Syscall-enter-stop и syscall-exit-stop неотличимы от друг друга по трассировщику. Трассировщик должен отслеживать последовательность ptrace-stop, чтобы не ошибочно интерпретировать syscall-enter- остановка как syscall-exit-stop или наоборот.

Когда я присоединяюсь к процессу, используя PTRACE_ATTACH, как мне узнать, находится ли трассировка в данный момент в системном вызове или нет? Иными словами, если я перезапущу трассировку, используя PTRACE_SYSCALL, как мне узнать, является ли следующий syscall-stop syscall-enter-stop или syscall-exit-stop?

Ответы [ 3 ]

0 голосов
/ 28 августа 2018

Когда я присоединяюсь к процессу, используя PTRACE_ATTACH, как мне узнать, находится ли трассировка в системном вызове или нет?

Когда вы присоединяетесь к процессу, используя PTRACE_ATTACH, трассировке отправляется сигнал STOP.

Сигнал STOP может вступить в силу при выполнении кода пользовательского пространства, при вводе системного вызова, при блокировке «медленного» системного вызова в ядре и при возврате в пользовательское пространство из системного вызова.

Исследуя указатель инструкций и инструкции вокруг указателя инструкций, вы обычно можете определить, выполнял ли процесс код пользовательского пространства, но это все.

Однако, поскольку точка останова является, по сути, случайной, вы можете дождаться остановки процесса, а затем пошагово каждый из его потоков, используя PTRACE_SINGLESTEP, пока указатель инструкции не изменится. Тогда вы знаете, что поток выполняет код пользовательского пространства.

В качестве альтернативы, если одиночный шаг приводит к тому, что поток блокируется в течение длительного времени, это означает, что поток выполняет медленный системный вызов, который блокирует.

Иными словами, если я перезапущу трассировку с помощью PTRACE_SYSCALL, как мне узнать, является ли следующий syscall-stop syscall-enter-stop или syscall-exit-stop?

Нет, если вы не знаете, в каком месте остановилась трассировка. Как я уже отмечал выше, это можно сделать, пошагово выполняя код, пока указатель инструкции не изменится.

0 голосов
/ 16 апреля 2019

Когда отслеживаемый процесс останавливается на входе системного вызова, регистр EAX будет содержать -ENOSYS, а у orig_rax есть номер этого системного вызова.

Следующий пример кода демонстрирует пример.

if (registers.rax == -ENOSYS)
                { switch (registers.orig_rax)
                        {
                          case _NR_open: //Example
                          break;
                          default:
                    // to get the arguments

                        fprintf(stderr, "%#08x, %#08x, %#08x",
                                registers.rbx, registers.rcx, 
                                                registers.rdx);
                     break;
                     }
              }
              else
              {
                if (registers.rax < 0)
                {
                        // error condition
                        fprintf(stderr, "#Err: %s\n", 
                 errors[abs(registers.rax)]);
                }
                else
                {
                        // return code
                        fprintf(stderr, "%#08x\n", registers.rax);
                }
        }
0 голосов
/ 28 августа 2018

Я не верю, что вы можете сделать это с ptrace. ptrace traces , в конце концов, то есть он отображает события и не имеет возможности проверить историю (он не имеет представления о стеке отслеживаемого процесса).

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

$ gdb -p 20334
...
Attaching to process 20334
...
> bt

Это даст вам трассировку стека процесса. Если у вас установлены отладочные символы вашего ядра, вы можете увидеть список функций ядра (вместо просто «???»).

...