PTRACE_CONT后,PTRACE_分离失败,错误号=ESRCH

PTRACE_CONT后,PTRACE_分离失败,错误号=ESRCH,c,linux,ptrace,C,Linux,Ptrace,在我的项目中,我需要附加到进程,恢复它们,然后使用ptrace分离它们。但是,分离失败,因为errno=ESRCH(没有这样的过程) 如果我不使用PTRACE\u CONT继续进程,分离工作正常,但在这种情况下,进程停止/无响应,这在我的项目中是不可接受的。在Arch和Ubuntu12.04 LTS上测试,结果相同 #include <stdio.h> #include <errno.h> #include <fcntl.h> #include <sys

在我的项目中,我需要附加到进程,恢复它们,然后使用
ptrace
分离它们。但是,分离失败,因为
errno=ESRCH(没有这样的过程)

如果我不使用
PTRACE\u CONT
继续进程,分离工作正常,但在这种情况下,进程停止/无响应,这在我的项目中是不可接受的。在Arch和Ubuntu12.04 LTS上测试,结果相同

#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ptrace.h>
#include <sys/wait.h>

int main(int argc, char *argv[])
{
    pid_t pid = 21000;

    if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1) {
        perror("PTRACE_ATTACH");
        return 1;
    } 
    printf("attached\n");
    waitpid(pid, NULL, WUNTRACED);

    if (ptrace(PTRACE_CONT, pid, NULL, NULL) == -1) {
        perror("PTRACE_CONT");
        return 1;
    }
    printf("continued\n");

    if (ptrace(PTRACE_DETACH, pid, NULL, NULL) == -1) {
        perror("PTRACE_DETACH");
        return 1;
    }
    printf("detached\n");

    return 0;
}

根据
ptrace
手册页,在尝试从进程中分离之前,应停止进程:

tracee的分离通过以下方式执行:

ptrace(ptrace_分离,pid,0,sig)

PTU分离是一种重新启动操作;因此,它需要 tracee将在ptrace停止。如果tracee处于信号传递中- 停止,可以注入信号。否则,sig参数可能为 默默地忽略。 如果跟踪程序要分离tracee时tracee正在运行,则 通常的解决方案是发送SIGSTOP(使用tgkill(2))以确保 转到正确的线程),等待tracee在信号中停止- SIGSTOP的输送停止装置,然后将其分离(抑制SIGSTOP 注射)。一个设计缺陷是,这可能与并发 他停了下来。另一个复杂的情况是tracee可能会进入其他领域 ptrace停止,需要重新启动并再次等待,直到 可以看到SIGSTOP。另一个复杂问题是要确保 tracee尚未停止,因为没有信号传递 就在此时发生,甚至不停止

在您的示例代码中,实际上不需要调用
ptrace(ptrace\u CONT,…)
。您可以从流程中分离。如果该代码属于较大的代码段,则可以只使用
tgkill()
(或者如果不使用线程,只需使用
kill
):


这样一个进程执行需要多长时间?目标进程可以无限执行。我认为这可能是一个时间问题,但在PTRACE_CONT之后添加sleep(10)并没有解决失败的分离问题。
attached
continued
PTRACE_DETACH: No such process
ptrace(PTRACE_CONT, ...);
kill(pid, SIGSTOP);
waitpid(pid, NULL, 0);
ptrace(PTRACE_DETACH, ...);