Ptrace предотвращает прерывание сигнала pselect () в процессе трассировки

Ptrace предотвращает прерывание сигнала pselect () в процессе трассировки

13.07.2016 12:24:59 Просмотров 17 Источник

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

При выполнении с ptrace он выходит из sys_pselect6, но не полностью из pselect glibc. Что я делаю, чтобы предотвратить выход sys_pselect6 из пользовательского кода ?

Трассер:

#include <stdio.h>
#include <sys/ptrace.h>
#include <sys/reg.h>
#include <err.h>
#include <wait.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    int pid = fork(), sys_in = 1, status;

    if (pid == 0) {
        if (ptrace(PTRACE_TRACEME, getppid(), NULL, NULL) < 0)
            err(1, "TRACEME()");

        execl("./child", "./child", NULL);
        err(1, "execl()");
    }

    if (waitpid(pid, &status, 0) != pid) err(1, "wait()");

    for (;; sys_in ^= 1) {
        if (ptrace(PTRACE_SYSCALL, pid, NULL, NULL) < 0) err(1, "SYSCALL");

        if (waitpid(pid, &status, 0) != pid) err(1, "wait()");

        if (sys_in) {
            long long sys_no = ptrace(PTRACE_PEEKUSER, pid, 8 * ORIG_RAX, NULL);
            printf("syscall entry %lld\n", sys_no);
        }
        else printf("syscall exit\n");
    }
    return 0;
}

Ребенок:

#include <stdio.h>
#include <sys/select.h>
#include <signal.h>
#include <err.h>

void handle_sigquit(int sig, siginfo_t* info, void *ctx)
{
}

int main()
{
    sigset_t mask;
    sigset_t orig_mask;
    struct sigaction sa = {};

    sa.sa_flags = SA_SIGINFO;
    sa.sa_sigaction = handle_sigquit;
    sigaction(SIGQUIT, &sa, NULL);

    sigemptyset(&mask);
    sigaddset(&mask, SIGQUIT);

    if (sigprocmask(SIG_BLOCK, &mask, &orig_mask) < 0) err(1, "sigprocmask()");

    pselect(0, NULL, NULL, NULL, NULL, &orig_mask);
    warn("pselect()");
    return 0;
}
У вопроса есть решение - Посмотреть?

Ответы - Ptrace предотвращает прерывание сигнала pselect () в процессе трассировки / Ptrace prevents signal from interrupting pselect() in traced process

Является ответом!
Shachar Shemesh

04.10.2016 09:16:18

ptrace(PTRACE_SYSCALL, pid, NULL, NULL)

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

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

При обработке ptraceили что-то еще. Если это что-то другое, лучше всего передать ее с процессом отлаживаемого кода.

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

Закрыть X